1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <osl/diagnose.h>
21 #include <svtools/htmlout.hxx>
22 #include <svtools/htmlkywd.hxx>
23 #include <rtl/strbuf.hxx>
24 #include <ndindex.hxx>
25 #include <fmtftn.hxx>
26 #include <txtftn.hxx>
27 #include <ftninfo.hxx>
28 #include <doc.hxx>
29 #include <ndtxt.hxx>
30 #include <charfmt.hxx>
31 
32 #include "swhtml.hxx"
33 #include "wrthtml.hxx"
34 
lcl_html_getNextPart(OUString & rPart,const OUString & rContent,sal_Int32 nPos)35 static sal_Int32 lcl_html_getNextPart( OUString& rPart, const OUString& rContent,
36                              sal_Int32 nPos )
37 {
38     rPart.clear();
39     sal_Int32 nLen = rContent.getLength();
40     if( nPos >= nLen )
41     {
42         nPos = -1;
43     }
44     else
45     {
46         bool bQuoted = false, bDone = false;
47         for( ; nPos < nLen && !bDone; nPos++ )
48         {
49             sal_Unicode c = rContent[nPos];
50             switch( c )
51             {
52             case '\\':
53                 if( bQuoted )
54                     rPart += OUStringChar( c );
55                 bQuoted = !bQuoted;
56                 break;
57 
58             case ';':
59                 if( bQuoted )
60                     rPart += OUStringChar( c );
61                 else
62                     bDone = true;
63                 bQuoted = false;
64                 break;
65 
66             default:
67                 rPart += OUStringChar( c );
68                 bQuoted = false;
69                 break;
70             }
71         }
72     }
73 
74     return nPos;
75 }
76 
lcl_html_getEndNoteInfo(SwEndNoteInfo & rInfo,const OUString & rContent,bool bEndNote)77 static sal_Int32 lcl_html_getEndNoteInfo( SwEndNoteInfo& rInfo,
78                                     const OUString& rContent,
79                                     bool bEndNote )
80 {
81     sal_Int32 nStrPos = 0;
82     for( int nPart = 0; nPart < 4; ++nPart )
83     {
84         OUString aPart;
85         if( -1 != nStrPos )
86             nStrPos = lcl_html_getNextPart( aPart, rContent, nStrPos );
87 
88         switch( nPart )
89         {
90         case 0:
91             rInfo.aFormat.SetNumberingType( bEndNote ? SVX_NUM_ROMAN_LOWER : SVX_NUM_ARABIC );
92             if( !aPart.isEmpty() )
93                 rInfo.aFormat.SetNumberingType(SwHTMLParser::GetNumType( aPart,
94                                                              rInfo.aFormat.GetNumberingType() ));
95             break;
96 
97         case 1:
98             rInfo.nFootnoteOffset = aPart.isEmpty() ? 0 : static_cast<sal_uInt16>(aPart.toInt32());
99             break;
100 
101         case 2:
102             rInfo.SetPrefix( aPart );
103             break;
104 
105         case 3:
106             rInfo.SetSuffix( aPart );
107             break;
108         }
109     }
110 
111     return nStrPos;
112 }
113 
FillEndNoteInfo(const OUString & rContent)114 void SwHTMLParser::FillEndNoteInfo( const OUString& rContent )
115 {
116     SwEndNoteInfo aInfo( m_xDoc->GetEndNoteInfo() );
117     lcl_html_getEndNoteInfo( aInfo, rContent, true );
118     m_xDoc->SetEndNoteInfo( aInfo );
119 }
120 
FillFootNoteInfo(const OUString & rContent)121 void SwHTMLParser::FillFootNoteInfo( const OUString& rContent )
122 {
123     SwFootnoteInfo aInfo( m_xDoc->GetFootnoteInfo() );
124 
125     sal_Int32 nStrPos = lcl_html_getEndNoteInfo( aInfo, rContent, false );
126 
127     for( int nPart = 4; nPart < 8; ++nPart )
128     {
129         OUString aPart;
130         if( -1 != nStrPos )
131             nStrPos = lcl_html_getNextPart( aPart, rContent, nStrPos );
132 
133         switch( nPart )
134         {
135         case 4:
136             aInfo.eNum = FTNNUM_DOC;
137             if( !aPart.isEmpty() )
138             {
139                 switch( aPart[0] )
140                 {
141                 case 'D': aInfo.eNum = FTNNUM_DOC; break;
142                 case 'C': aInfo.eNum = FTNNUM_CHAPTER; break;
143                 case 'P': aInfo.eNum = FTNNUM_PAGE; break;
144                 }
145             }
146             break;
147 
148         case 5:
149             aInfo.ePos = FTNPOS_PAGE;
150             if( !aPart.isEmpty() )
151             {
152                 switch( aPart[0] )
153                 {
154                 case 'C': aInfo.ePos = FTNPOS_CHAPTER; break;
155                 case 'P': aInfo.ePos = FTNPOS_PAGE; break;
156                 }
157             }
158             break;
159 
160         case 6:
161             aInfo.aQuoVadis = aPart;
162             break;
163 
164         case 7:
165             aInfo.aErgoSum = aPart;
166             break;
167         }
168     }
169 
170     m_xDoc->SetFootnoteInfo( aInfo );
171 }
172 
InsertFootEndNote(const OUString & rName,bool bEndNote,bool bFixed)173 void SwHTMLParser::InsertFootEndNote( const OUString& rName, bool bEndNote,
174                                       bool bFixed )
175 {
176     if( !m_pFootEndNoteImpl )
177         m_pFootEndNoteImpl.reset(new SwHTMLFootEndNote_Impl);
178 
179     m_pFootEndNoteImpl->sName = rName;
180     if( m_pFootEndNoteImpl->sName.getLength() > 3 )
181         m_pFootEndNoteImpl->sName = m_pFootEndNoteImpl->sName.copy( 0, m_pFootEndNoteImpl->sName.getLength() - 3 );
182     m_pFootEndNoteImpl->sName = m_pFootEndNoteImpl->sName.toAsciiUpperCase();
183     m_pFootEndNoteImpl->bEndNote = bEndNote;
184     m_pFootEndNoteImpl->bFixed = bFixed;
185     m_pFootEndNoteImpl->sContent.clear();
186 }
187 
FinishFootEndNote()188 void SwHTMLParser::FinishFootEndNote()
189 {
190     if( !m_pFootEndNoteImpl )
191         return;
192 
193     SwFormatFootnote aFootnote( m_pFootEndNoteImpl->bEndNote );
194     if( m_pFootEndNoteImpl->bFixed )
195         aFootnote.SetNumStr( m_pFootEndNoteImpl->sContent );
196 
197     m_xDoc->getIDocumentContentOperations().InsertPoolItem( *m_pPam, aFootnote );
198     SwTextFootnote * const pTextFootnote = static_cast<SwTextFootnote *>(
199         m_pPam->GetNode().GetTextNode()->GetTextAttrForCharAt(
200             m_pPam->GetPoint()->nContent.GetIndex() - 1, RES_TXTATR_FTN ) );
201     // In header and footer no footnotes can be inserted.
202     if (pTextFootnote)
203         m_pFootEndNoteImpl->aTextFootnotes.push_back(SwHTMLTextFootnote(m_pFootEndNoteImpl->sName,pTextFootnote));
204     m_pFootEndNoteImpl->sName.clear();
205     m_pFootEndNoteImpl->sContent.clear();
206     m_pFootEndNoteImpl->bFixed = false;
207 }
208 
InsertFootEndNoteText()209 void SwHTMLParser::InsertFootEndNoteText()
210 {
211     if( m_pFootEndNoteImpl && m_pFootEndNoteImpl->bFixed )
212         m_pFootEndNoteImpl->sContent += aToken;
213 }
214 
DeleteFootEndNoteImpl()215 void SwHTMLParser::DeleteFootEndNoteImpl()
216 {
217     m_pFootEndNoteImpl.reset();
218 }
219 
GetFootEndNoteSection(const OUString & rName)220 SwNodeIndex *SwHTMLParser::GetFootEndNoteSection( const OUString& rName )
221 {
222     SwNodeIndex *pStartNodeIdx = nullptr;
223 
224     if (m_pFootEndNoteImpl)
225     {
226         OUString aName(rName.toAsciiUpperCase());
227 
228         size_t nCount = m_pFootEndNoteImpl->aTextFootnotes.size();
229         for(size_t i = 0; i < nCount; ++i)
230         {
231             if (m_pFootEndNoteImpl->aTextFootnotes[i].sName == aName)
232             {
233                 pStartNodeIdx = m_pFootEndNoteImpl->aTextFootnotes[i].pTextFootnote->GetStartNode();
234                 m_pFootEndNoteImpl->aTextFootnotes.erase( m_pFootEndNoteImpl->aTextFootnotes.begin() + i );
235                 if (m_pFootEndNoteImpl->aTextFootnotes.empty())
236                 {
237                     m_pFootEndNoteImpl.reset();
238                 }
239 
240                 break;
241             }
242         }
243     }
244 
245     return pStartNodeIdx;
246 }
247 
OutHTML_SwFormatFootnote(Writer & rWrt,const SfxPoolItem & rHt)248 Writer& OutHTML_SwFormatFootnote( Writer& rWrt, const SfxPoolItem& rHt )
249 {
250     SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
251 
252     SwFormatFootnote& rFormatFootnote = const_cast<SwFormatFootnote&>(static_cast<const SwFormatFootnote&>(rHt));
253     SwTextFootnote *pTextFootnote = rFormatFootnote.GetTextFootnote();
254     if( !pTextFootnote )
255         return rWrt;
256 
257     OUString sFootnoteName, sClass;
258     size_t nPos;
259     if( rFormatFootnote.IsEndNote() )
260     {
261         nPos = rHTMLWrt.m_pFootEndNotes ? rHTMLWrt.m_pFootEndNotes->size() : 0;
262         OSL_ENSURE( nPos == static_cast<size_t>(rHTMLWrt.m_nFootNote + rHTMLWrt.m_nEndNote),
263                 "OutHTML_SwFormatFootnote: wrong position" );
264         sClass = OOO_STRING_SVTOOLS_HTML_sdendnote_anc;
265         sFootnoteName = OOO_STRING_SVTOOLS_HTML_sdendnote + OUString::number( static_cast<sal_Int32>(++rHTMLWrt.m_nEndNote) );
266     }
267     else
268     {
269         nPos = rHTMLWrt.m_nFootNote;
270         sClass = OOO_STRING_SVTOOLS_HTML_sdfootnote_anc;
271         sFootnoteName = OOO_STRING_SVTOOLS_HTML_sdfootnote + OUString::number( static_cast<sal_Int32>(++rHTMLWrt.m_nFootNote));
272     }
273 
274     if( !rHTMLWrt.m_pFootEndNotes )
275         rHTMLWrt.m_pFootEndNotes.reset(new std::vector<SwTextFootnote*>);
276     rHTMLWrt.m_pFootEndNotes->insert( rHTMLWrt.m_pFootEndNotes->begin() + nPos, pTextFootnote );
277 
278     OStringBuffer sOut;
279     OString aTag = rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_anchor;
280     sOut.append("<" + aTag + " " OOO_STRING_SVTOOLS_HTML_O_class "=\"");
281     rWrt.Strm().WriteOString( sOut.makeStringAndClear() );
282     HTMLOutFuncs::Out_String( rWrt.Strm(), sClass, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
283     sOut.append("\" " OOO_STRING_SVTOOLS_HTML_O_name "=\"");
284     rWrt.Strm().WriteOString( sOut.makeStringAndClear() );
285     HTMLOutFuncs::Out_String( rWrt.Strm(), sFootnoteName, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
286     sOut.append(OOO_STRING_SVTOOLS_HTML_FTN_anchor "\" "
287                 OOO_STRING_SVTOOLS_HTML_O_href "=\"#");
288     rWrt.Strm().WriteOString( sOut.makeStringAndClear() );
289     HTMLOutFuncs::Out_String( rWrt.Strm(), sFootnoteName, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
290     sOut.append(OOO_STRING_SVTOOLS_HTML_FTN_symbol "\"");
291     if( !rFormatFootnote.GetNumStr().isEmpty() )
292         sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_sdfixed);
293     sOut.append(">");
294     rWrt.Strm().WriteOString( sOut.makeStringAndClear() );
295     HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_superscript );
296 
297     HTMLOutFuncs::Out_String( rWrt.Strm(), rFormatFootnote.GetViewNumStr(*rWrt.m_pDoc, nullptr),
298                                  rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
299     HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_superscript, false );
300     HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_anchor, false );
301 
302     return rWrt;
303 }
304 
OutFootEndNotes()305 void SwHTMLWriter::OutFootEndNotes()
306 {
307     OSL_ENSURE( m_pFootEndNotes,
308             "SwHTMLWriter::OutFootEndNotes(): unnecessary call" );
309     if( !m_pFootEndNotes )
310         return;
311 
312 #if OSL_DEBUG_LEVEL > 0
313     sal_uInt16 nFootnote = m_nFootNote, nEn = m_nEndNote;
314 #endif
315     m_nFootNote = 0;
316     m_nEndNote = 0;
317 
318     for( auto *pTextFootnote : *m_pFootEndNotes )
319     {
320         m_pFormatFootnote = &pTextFootnote->GetFootnote();
321 
322         OUString sFootnoteName;
323         if( m_pFormatFootnote->IsEndNote() )
324         {
325             sFootnoteName = OOO_STRING_SVTOOLS_HTML_sdendnote + OUString::number(static_cast<sal_Int32>(++m_nEndNote));
326         }
327         else
328         {
329             sFootnoteName = OOO_STRING_SVTOOLS_HTML_sdfootnote + OUString::number(static_cast<sal_Int32>(++m_nFootNote));
330         }
331 
332         if( m_bLFPossible )
333             OutNewLine();
334         OString sOut =
335             "<" OOO_STRING_SVTOOLS_HTML_division
336             " " OOO_STRING_SVTOOLS_HTML_O_id "=\"";
337         Strm().WriteOString( sOut );
338         HTMLOutFuncs::Out_String( Strm(), sFootnoteName, m_eDestEnc, &m_aNonConvertableCharacters );
339         Strm().WriteCharPtr( "\">" );
340 
341         m_bLFPossible = true;
342         IncIndentLevel();   // indent content of <DIV>
343 
344         OSL_ENSURE( pTextFootnote, "SwHTMLWriter::OutFootEndNotes: SwTextFootnote is missing" );
345         SwNodeIndex *pSttNdIdx = pTextFootnote->GetStartNode();
346         OSL_ENSURE( pSttNdIdx,
347                 "SwHTMLWriter::OutFootEndNotes: StartNode-Index is missing" );
348         if( pSttNdIdx )
349         {
350             HTMLSaveData aSaveData( *this, pSttNdIdx->GetIndex()+1,
351                 pSttNdIdx->GetNode().EndOfSectionIndex(), false );
352             Out_SwDoc( m_pCurrentPam.get() );
353         }
354 
355         DecIndentLevel();   // indent content of <DIV>
356         if( m_bLFPossible )
357             OutNewLine();
358         HTMLOutFuncs::Out_AsciiTag( Strm(), GetNamespace() + OOO_STRING_SVTOOLS_HTML_division, false );
359         m_bLFPossible = true;
360 
361         OSL_ENSURE( !m_pFormatFootnote,
362                 "SwHTMLWriter::OutFootEndNotes: Footnote was not output" );
363         if( m_pFormatFootnote )
364         {
365             if( m_pFormatFootnote->IsEndNote() )
366                 m_nEndNote++;
367             else
368                 m_nFootNote++;
369 
370             m_pFormatFootnote = nullptr;
371         }
372     }
373 
374 #if OSL_DEBUG_LEVEL > 0
375     OSL_ENSURE( nFootnote == m_nFootNote,
376             "SwHTMLWriter::OutFootEndNotes: Number of footnotes does not match" );
377     OSL_ENSURE( nEn == m_nEndNote,
378             "SwHTMLWriter::OutFootEndNotes: Number of endnotes does not match" );
379 #endif
380 
381     m_pFootEndNotes.reset();
382     m_nFootNote = m_nEndNote = 0;
383 }
384 
GetFootEndNoteSym(const SwFormatFootnote & rFormatFootnote)385 OUString SwHTMLWriter::GetFootEndNoteSym( const SwFormatFootnote& rFormatFootnote )
386 {
387     const SwEndNoteInfo * pInfo = nullptr;
388     if( rFormatFootnote.GetNumStr().isEmpty() )
389         pInfo = rFormatFootnote.IsEndNote() ? &m_pDoc->GetEndNoteInfo()
390                                     : &m_pDoc->GetFootnoteInfo();
391 
392     OUString sRet;
393     if( pInfo )
394         sRet = pInfo->GetPrefix();
395     sRet += rFormatFootnote.GetViewNumStr(*m_pDoc, nullptr);
396     if( pInfo )
397         sRet += pInfo->GetSuffix();
398 
399     return sRet;
400 }
401 
OutFootEndNoteSym(const SwFormatFootnote & rFormatFootnote,const OUString & rNum,sal_uInt16 nScript)402 void SwHTMLWriter::OutFootEndNoteSym( const SwFormatFootnote& rFormatFootnote,
403                                          const OUString& rNum,
404                                          sal_uInt16 nScript )
405 {
406     const SwEndNoteInfo *pInfo;
407 
408     OUString sFootnoteName, sClass;
409     if( rFormatFootnote.IsEndNote() )
410     {
411         sClass = OOO_STRING_SVTOOLS_HTML_sdendnote_sym;
412         sFootnoteName = OOO_STRING_SVTOOLS_HTML_sdendnote +
413             OUString::number(static_cast<sal_Int32>(m_nEndNote));
414         pInfo = &m_pDoc->GetEndNoteInfo();
415     }
416     else
417     {
418         sClass = OOO_STRING_SVTOOLS_HTML_sdfootnote_sym;
419         sFootnoteName = OOO_STRING_SVTOOLS_HTML_sdfootnote +
420             OUString::number(static_cast<sal_Int32>(m_nFootNote));
421         pInfo = &m_pDoc->GetFootnoteInfo();
422     }
423 
424     const SwCharFormat *pSymCharFormat = pInfo->GetCharFormat( *m_pDoc );
425     if( pSymCharFormat && 0 != m_aScriptTextStyles.count( pSymCharFormat->GetName() ) )
426     {
427         switch( nScript )
428         {
429         case CSS1_OUTMODE_WESTERN:
430             sClass += "-western";
431             break;
432         case CSS1_OUTMODE_CJK:
433             sClass += "-cjk";
434             break;
435         case CSS1_OUTMODE_CTL:
436             sClass += "-ctl";
437             break;
438         }
439     }
440 
441     OStringBuffer sOut;
442     sOut.append('<').append(GetNamespace() + OOO_STRING_SVTOOLS_HTML_anchor).append(' ')
443         .append(OOO_STRING_SVTOOLS_HTML_O_class).append("=\"");
444     Strm().WriteOString( sOut.makeStringAndClear() );
445     HTMLOutFuncs::Out_String( Strm(), sClass, m_eDestEnc, &m_aNonConvertableCharacters );
446     sOut.append("\" ").append(OOO_STRING_SVTOOLS_HTML_O_name).append("=\"");
447     Strm().WriteOString( sOut.makeStringAndClear() );
448     HTMLOutFuncs::Out_String( Strm(), sFootnoteName, m_eDestEnc, &m_aNonConvertableCharacters );
449     sOut.append(OOO_STRING_SVTOOLS_HTML_FTN_symbol).append("\" ")
450         .append(OOO_STRING_SVTOOLS_HTML_O_href).append("=\"#");
451     Strm().WriteOString( sOut.makeStringAndClear() );
452     HTMLOutFuncs::Out_String( Strm(), sFootnoteName, m_eDestEnc, &m_aNonConvertableCharacters );
453     sOut.append(OOO_STRING_SVTOOLS_HTML_FTN_anchor).append("\">");
454     Strm().WriteOString( sOut.makeStringAndClear() );
455 
456     HTMLOutFuncs::Out_String( Strm(), rNum, m_eDestEnc, &m_aNonConvertableCharacters );
457     HTMLOutFuncs::Out_AsciiTag( Strm(), GetNamespace() + OOO_STRING_SVTOOLS_HTML_anchor, false );
458 }
459 
lcl_html_fillEndNoteInfo(const SwEndNoteInfo & rInfo,OUString * pParts,bool bEndNote)460 static int lcl_html_fillEndNoteInfo( const SwEndNoteInfo& rInfo,
461                                  OUString *pParts,
462                                  bool bEndNote  )
463 {
464     int nParts = 0;
465     sal_Int16 eFormat = rInfo.aFormat.GetNumberingType();
466     if( (bEndNote ? SVX_NUM_ROMAN_LOWER : SVX_NUM_ARABIC) != eFormat )
467     {
468         const sal_Char *pStr = SwHTMLWriter::GetNumFormat( eFormat );
469         if( pStr )
470         {
471             pParts[0] = OUString::createFromAscii( pStr );
472             nParts = 1;
473         }
474     }
475     if( rInfo.nFootnoteOffset > 0 )
476     {
477         pParts[1] = OUString::number(rInfo.nFootnoteOffset);
478         nParts = 2;
479     }
480     if( !rInfo.GetPrefix().isEmpty() )
481     {
482         pParts[2] = rInfo.GetPrefix();
483         nParts = 3;
484     }
485     if( !rInfo.GetSuffix().isEmpty() )
486     {
487         pParts[3] = rInfo.GetSuffix();
488         nParts = 4;
489     }
490 
491     return nParts;
492 }
493 
lcl_html_outFootEndNoteInfo(Writer & rWrt,OUString const * pParts,int nParts,const sal_Char * pName)494 static void lcl_html_outFootEndNoteInfo( Writer& rWrt, OUString const *pParts,
495                                   int nParts, const sal_Char *pName )
496 {
497     SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
498 
499     OUStringBuffer aContent;
500     for( int i=0; i<nParts; ++i )
501     {
502         OUString aTmp( pParts[i] );
503         aTmp = aTmp.replaceAll( "\\", "\\\\" );
504         aTmp = aTmp.replaceAll( ";", "\\;" );
505         if( i > 0 )
506             aContent.append(";");
507         aContent.append(aTmp);
508     }
509 
510     rHTMLWrt.OutNewLine();
511     OString sOut =
512         "<" OOO_STRING_SVTOOLS_HTML_meta " "
513         OOO_STRING_SVTOOLS_HTML_O_name "=\"" + rtl::OStringView(pName) +
514         "\" " OOO_STRING_SVTOOLS_HTML_O_content "=\"";
515     rWrt.Strm().WriteOString( sOut );
516     HTMLOutFuncs::Out_String( rWrt.Strm(), aContent.makeStringAndClear(), rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
517     rWrt.Strm().WriteCharPtr( "\">" );
518 }
519 
OutFootEndNoteInfo()520 void SwHTMLWriter::OutFootEndNoteInfo()
521 {
522     // Number type (1 or i)
523     // Offset (0)
524     // Before it
525     // Behind it
526     // Doc/Page/Chap (D)
527     // Position (S)
528     // Next page
529     // Beginning
530 
531     {
532         const SwFootnoteInfo& rInfo = m_pDoc->GetFootnoteInfo();
533         OUString aParts[8];
534         int nParts = lcl_html_fillEndNoteInfo( rInfo, aParts, false );
535         if( rInfo.eNum != FTNNUM_DOC )
536         {
537             aParts[4] = rInfo.eNum == FTNNUM_CHAPTER ? OUStringLiteral( "C" ) : OUStringLiteral( "P" );
538             nParts = 5;
539         }
540         if( rInfo.ePos != FTNPOS_PAGE)
541         {
542             aParts[5] = "C";
543             nParts = 6;
544         }
545         if( !rInfo.aQuoVadis.isEmpty() )
546         {
547             aParts[6] = rInfo.aQuoVadis;
548             nParts = 7;
549         }
550         if( !rInfo.aErgoSum.isEmpty() )
551         {
552             aParts[7] = rInfo.aErgoSum;
553             nParts = 8;
554         }
555         if( nParts > 0 )
556             lcl_html_outFootEndNoteInfo( *this, aParts, nParts,
557                                          OOO_STRING_SVTOOLS_HTML_META_sdfootnote );
558     }
559 
560     {
561         const SwEndNoteInfo& rInfo = m_pDoc->GetEndNoteInfo();
562         OUString aParts[4];
563         const int nParts = lcl_html_fillEndNoteInfo( rInfo, aParts, true );
564         if( nParts > 0 )
565             lcl_html_outFootEndNoteInfo( *this, aParts, nParts,
566                                          OOO_STRING_SVTOOLS_HTML_META_sdendnote );
567     }
568 }
569 
570 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
571