1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: htmlftn.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
37 #include <svtools/htmlout.hxx>
38 #include <svtools/htmlkywd.hxx>
40 #include <ndindex.hxx>
43 #include <ftninfo.hxx>
46 #include <charfmt.hxx>
50 #include "wrthtml.hxx"
52 typedef SwTxtFtn
*SwTxtFtnPtr
;
53 SV_DECL_PTRARR( SwHTMLTxtFtns
, SwTxtFtnPtr
, 1, 1 )
55 struct SwHTMLFootEndNote_Impl
57 SwHTMLTxtFtns aTxtFtns
;
61 String sContent
; // Infos fuer die letzte Fussnote
67 xub_StrLen
lcl_html_getNextPart( String
& rPart
, const String
& rContent
,
71 xub_StrLen nLen
= rContent
.Len();
78 BOOL bQuoted
= FALSE
, bDone
= FALSE
;
79 for( ; nPos
< nLen
&& !bDone
; nPos
++ )
81 sal_Unicode c
= rContent
.GetChar( nPos
);
109 xub_StrLen
lcl_html_getEndNoteInfo( SwEndNoteInfo
& rInfo
,
110 const String
& rContent
,
113 xub_StrLen nStrPos
= 0;
114 for( USHORT nPart
= 0; nPart
< 4; nPart
++ )
117 if( STRING_MAXLEN
!= nStrPos
)
118 nStrPos
= lcl_html_getNextPart( aPart
, rContent
, nStrPos
);
123 rInfo
.aFmt
.SetNumberingType( static_cast< sal_Int16
>(bEndNote
? SVX_NUM_ROMAN_LOWER
: SVX_NUM_ARABIC
));
125 rInfo
.aFmt
.SetNumberingType(SwHTMLParser::GetNumType( aPart
,
126 rInfo
.aFmt
.GetNumberingType() ));
130 rInfo
.nFtnOffset
= aPart
.Len() == 0 ? 0 : (USHORT
)aPart
.ToInt32();
134 rInfo
.SetPrefix( aPart
);
138 rInfo
.SetSuffix( aPart
);
146 void SwHTMLParser::FillEndNoteInfo( const String
& rContent
)
148 SwEndNoteInfo
aInfo( pDoc
->GetEndNoteInfo() );
149 lcl_html_getEndNoteInfo( aInfo
, rContent
, TRUE
);
150 pDoc
->SetEndNoteInfo( aInfo
);
153 void SwHTMLParser::FillFootNoteInfo( const String
& rContent
)
155 SwFtnInfo
aInfo( pDoc
->GetFtnInfo() );
157 xub_StrLen nStrPos
= lcl_html_getEndNoteInfo( aInfo
, rContent
, FALSE
);
159 for( USHORT nPart
= 4; nPart
< 8; nPart
++ )
162 if( STRING_MAXLEN
!= nStrPos
)
163 nStrPos
= lcl_html_getNextPart( aPart
, rContent
, nStrPos
);
168 aInfo
.eNum
= FTNNUM_DOC
;
171 switch( aPart
.GetChar(0) )
173 case 'D': aInfo
.eNum
= FTNNUM_DOC
; break;
174 case 'C': aInfo
.eNum
= FTNNUM_CHAPTER
; break;
175 case 'P': aInfo
.eNum
= FTNNUM_PAGE
; break;
181 aInfo
.ePos
= FTNPOS_PAGE
;
184 switch( aPart
.GetChar(0) )
186 case 'C': aInfo
.ePos
= FTNPOS_CHAPTER
; break;
187 case 'P': aInfo
.ePos
= FTNPOS_PAGE
; break;
193 aInfo
.aQuoVadis
= aPart
;
197 aInfo
.aErgoSum
= aPart
;
202 pDoc
->SetFtnInfo( aInfo
);
205 void SwHTMLParser::InsertFootEndNote( const String
& rName
, BOOL bEndNote
,
208 if( !pFootEndNoteImpl
)
209 pFootEndNoteImpl
= new SwHTMLFootEndNote_Impl
;
211 pFootEndNoteImpl
->sName
= rName
;
212 if( pFootEndNoteImpl
->sName
.Len() > 3 )
213 pFootEndNoteImpl
->sName
.Erase( pFootEndNoteImpl
->sName
.Len() - 3 );
214 // TODO: ToUpperAscii???
215 pFootEndNoteImpl
->sName
.ToUpperAscii();
217 pFootEndNoteImpl
->bEndNote
= bEndNote
;
218 pFootEndNoteImpl
->bFixed
= bFixed
;
219 pFootEndNoteImpl
->sContent
= aEmptyStr
;
222 void SwHTMLParser::FinishFootEndNote()
224 if( !pFootEndNoteImpl
)
227 SwFmtFtn
aFtn( pFootEndNoteImpl
->bEndNote
);
228 if( pFootEndNoteImpl
->bFixed
)
229 aFtn
.SetNumStr( pFootEndNoteImpl
->sContent
);
231 pDoc
->InsertPoolItem( *pPam
, aFtn
, 0 );
232 SwTxtFtn
* const pTxtFtn
= static_cast<SwTxtFtn
*>(
233 pPam
->GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
234 pPam
->GetPoint()->nContent
.GetIndex() - 1, RES_TXTATR_FTN
) );
235 // In Kopf- und Fusszeilen duerfen keine Fussnoten eingefuegt werden.
238 pFootEndNoteImpl
->aTxtFtns
.Insert( pTxtFtn
,
239 pFootEndNoteImpl
->aTxtFtns
.Count() );
241 pFootEndNoteImpl
->aNames
.Insert( new String(pFootEndNoteImpl
->sName
),
242 pFootEndNoteImpl
->aNames
.Count() );
244 pFootEndNoteImpl
->sName
= aEmptyStr
;
245 pFootEndNoteImpl
->sContent
= aEmptyStr
;
246 pFootEndNoteImpl
->bFixed
= FALSE
;
249 void SwHTMLParser::InsertFootEndNoteText()
251 if( pFootEndNoteImpl
&& pFootEndNoteImpl
->bFixed
)
252 pFootEndNoteImpl
->sContent
+= aToken
;
255 void SwHTMLParser::DeleteFootEndNoteImpl()
257 delete pFootEndNoteImpl
;
258 pFootEndNoteImpl
= 0;
261 SwNodeIndex
*SwHTMLParser::GetFootEndNoteSection( const String
& rName
)
263 SwNodeIndex
*pStartNodeIdx
= 0;
265 if( pFootEndNoteImpl
)
267 String
aName( rName
);
268 // TODO: ToUpperAscii
269 aName
.ToUpperAscii();
271 USHORT nCount
= pFootEndNoteImpl
->aNames
.Count();
272 for( USHORT i
=0; i
<nCount
; i
++ )
274 if( *pFootEndNoteImpl
->aNames
[i
] == aName
)
276 pStartNodeIdx
= pFootEndNoteImpl
->aTxtFtns
[i
]->GetStartNode();
277 pFootEndNoteImpl
->aNames
.DeleteAndDestroy( i
, 1 );
278 pFootEndNoteImpl
->aTxtFtns
.Remove( i
, 1 );
279 if( !pFootEndNoteImpl
->aNames
.Count() )
281 delete pFootEndNoteImpl
;
282 pFootEndNoteImpl
= 0;
290 return pStartNodeIdx
;
293 Writer
& OutHTML_SwFmtFtn( Writer
& rWrt
, const SfxPoolItem
& rHt
)
295 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
297 SwFmtFtn
& rFmtFtn
= (SwFmtFtn
&)rHt
;
298 SwTxtFtn
*pTxtFtn
= rFmtFtn
.GetTxtFtn();
302 String sFtnName
, sClass
;
304 if( rFmtFtn
.IsEndNote() )
306 nPos
= rHTMLWrt
.pFootEndNotes
? rHTMLWrt
.pFootEndNotes
->Count() : 0;
307 ASSERT( nPos
== rHTMLWrt
.nFootNote
+ rHTMLWrt
.nEndNote
,
308 "OutHTML_SwFmtFtn: Position falsch" );
309 sClass
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote_anc
);
310 sFtnName
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote
);
311 sFtnName
+= String::CreateFromInt32( (sal_Int32
)(++rHTMLWrt
.nEndNote
) );
315 nPos
= rHTMLWrt
.nFootNote
;
316 sClass
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote_anc
);
317 sFtnName
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote
);
318 sFtnName
+= String::CreateFromInt32( (sal_Int32
)(++rHTMLWrt
.nFootNote
));
321 if( !rHTMLWrt
.pFootEndNotes
)
322 rHTMLWrt
.pFootEndNotes
= new SwHTMLTxtFtns
;
323 rHTMLWrt
.pFootEndNotes
->Insert( pTxtFtn
, nPos
);
325 ByteString
sOut( '<' );
326 (((sOut
+= OOO_STRING_SVTOOLS_HTML_anchor
) += ' ') += OOO_STRING_SVTOOLS_HTML_O_class
) += "=\"";
327 rWrt
.Strm() << sOut
.GetBuffer();
328 HTMLOutFuncs::Out_String( rWrt
.Strm(), sClass
, rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
329 ((sOut
= "\" ") += OOO_STRING_SVTOOLS_HTML_O_name
) += "=\"";
330 rWrt
.Strm() << sOut
.GetBuffer();
331 HTMLOutFuncs::Out_String( rWrt
.Strm(), sFtnName
, rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
332 (((sOut
= OOO_STRING_SVTOOLS_HTML_FTN_anchor
) += "\" ") += OOO_STRING_SVTOOLS_HTML_O_href
) += "=\"#";
333 rWrt
.Strm() << sOut
.GetBuffer();
334 HTMLOutFuncs::Out_String( rWrt
.Strm(), sFtnName
, rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
335 (sOut
= OOO_STRING_SVTOOLS_HTML_FTN_symbol
)+= '\"';
336 if( rFmtFtn
.GetNumStr().Len() )
337 (sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_sdfixed
;
339 rWrt
.Strm() << sOut
.GetBuffer();
340 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_superscript
, TRUE
);
342 HTMLOutFuncs::Out_String( rWrt
.Strm(), rFmtFtn
.GetViewNumStr(*rWrt
.pDoc
),
343 rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
344 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_superscript
, FALSE
);
345 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_anchor
, FALSE
);
350 void SwHTMLWriter::OutFootEndNotes()
352 ASSERT( pFootEndNotes
,
353 "SwHTMLWriter::OutFootEndNotes(): unnoetiger Aufruf" );
358 USHORT nFtn
= nFootNote
, nEn
= nEndNote
;
360 nFootNote
= 0, nEndNote
= 0;
362 for( USHORT i
=0; i
<pFootEndNotes
->Count(); i
++ )
364 SwTxtFtn
*pTxtFtn
= (*pFootEndNotes
)[i
];
365 pFmtFtn
= &pTxtFtn
->GetFtn();
367 String sFtnName
, sClass
;
368 if( pFmtFtn
->IsEndNote() )
370 sClass
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote
);
371 sFtnName
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote
);
372 sFtnName
.Append( String::CreateFromInt32((sal_Int32
)(++nEndNote
)) );
376 sClass
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote
);
377 sFtnName
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote
);
378 sFtnName
.Append( String::CreateFromInt32((sal_Int32
)(++nFootNote
)));
383 ByteString
sOut( '<' );
384 (((sOut
+= OOO_STRING_SVTOOLS_HTML_division
) += ' ') += OOO_STRING_SVTOOLS_HTML_O_id
) += "=\"";
385 Strm() << sOut
.GetBuffer();
386 HTMLOutFuncs::Out_String( Strm(), sFtnName
, eDestEnc
, &aNonConvertableCharacters
);
390 IncIndentLevel(); // Inhalt von <DIV> einruecken
392 ASSERT( pTxtFtn
, "SwHTMLWriter::OutFootEndNotes: SwTxtFtn fehlt" );
393 SwNodeIndex
*pSttNdIdx
= pTxtFtn
->GetStartNode();
395 "SwHTMLWriter::OutFootEndNotes: StartNode-Index fehlt" );
398 HTMLSaveData
aSaveData( *this, pSttNdIdx
->GetIndex()+1,
399 pSttNdIdx
->GetNode().EndOfSectionIndex(), FALSE
);
400 Out_SwDoc( pCurPam
);
403 DecIndentLevel(); // Inhalt von <DIV> einruecken
406 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_division
, FALSE
);
410 "SwHTMLWriter::OutFootEndNotes: Ftn wurde nicht ausgegeben" );
413 if( pFmtFtn
->IsEndNote() )
423 ASSERT( nFtn
== nFootNote
,
424 "SwHTMLWriter::OutFootEndNotes: Anzahl Fussnoten stimmt nicht" );
425 ASSERT( nEn
== nEndNote
,
426 "SwHTMLWriter::OutFootEndNotes: Anzahl Endnoten stimmt nicht" );
429 delete pFootEndNotes
;
431 nFootNote
= nEndNote
= 0;
434 String
SwHTMLWriter::GetFootEndNoteSym( const SwFmtFtn
& rFmtFtn
)
436 const SwEndNoteInfo
* pInfo
= 0;
437 if( rFmtFtn
.GetNumStr().Len() == 0 )
438 pInfo
= rFmtFtn
.IsEndNote() ? &pDoc
->GetEndNoteInfo()
439 : &pDoc
->GetFtnInfo();
443 sRet
= pInfo
->GetPrefix();
444 sRet
+= rFmtFtn
.GetViewNumStr( *pDoc
);
446 sRet
+= pInfo
->GetSuffix();
451 void SwHTMLWriter::OutFootEndNoteSym( const SwFmtFtn
& rFmtFtn
,
455 const SwEndNoteInfo
*pInfo
;
457 String sFtnName
, sClass
, sPrefix
, sSuffix
;
458 if( rFmtFtn
.IsEndNote() )
460 sClass
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote_sym
);
461 sFtnName
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote
);
462 sFtnName
.Append( String::CreateFromInt32((sal_Int32
)nEndNote
) );
463 pInfo
= &pDoc
->GetEndNoteInfo();
467 sClass
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote_sym
);
468 sFtnName
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote
);
469 sFtnName
.Append( String::CreateFromInt32((sal_Int32
)nFootNote
));
470 pInfo
= &pDoc
->GetFtnInfo();
473 const SwCharFmt
*pSymCharFmt
= pInfo
->GetCharFmt( *pDoc
);
474 if( pSymCharFmt
&& aScriptTextStyles
.Seek_Entry( (String
*)&pSymCharFmt
->GetName() ) )
478 case CSS1_OUTMODE_WESTERN
:
479 sClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-western") );
481 case CSS1_OUTMODE_CJK
:
482 sClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-cjk") );
484 case CSS1_OUTMODE_CTL
:
485 sClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-ctl") );
490 ByteString
sOut( '<' );
491 (((sOut
+= OOO_STRING_SVTOOLS_HTML_anchor
) += ' ') += OOO_STRING_SVTOOLS_HTML_O_class
) += "=\"";
492 Strm() << sOut
.GetBuffer();
493 HTMLOutFuncs::Out_String( Strm(), sClass
, eDestEnc
, &aNonConvertableCharacters
);
494 ((sOut
= "\" ") += OOO_STRING_SVTOOLS_HTML_O_name
) += "=\"";
495 Strm() << sOut
.GetBuffer();
496 HTMLOutFuncs::Out_String( Strm(), sFtnName
, eDestEnc
, &aNonConvertableCharacters
);
497 (((sOut
= OOO_STRING_SVTOOLS_HTML_FTN_symbol
) +="\" ") += OOO_STRING_SVTOOLS_HTML_O_href
) += "=\"#";
498 Strm() << sOut
.GetBuffer();
499 HTMLOutFuncs::Out_String( Strm(), sFtnName
, eDestEnc
, &aNonConvertableCharacters
);
500 (sOut
= OOO_STRING_SVTOOLS_HTML_FTN_anchor
) += "\">";
501 Strm() << sOut
.GetBuffer();
503 HTMLOutFuncs::Out_String( Strm(), rNum
, eDestEnc
, &aNonConvertableCharacters
);
504 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_anchor
, FALSE
);
507 USHORT
lcl_html_fillEndNoteInfo( const SwEndNoteInfo
& rInfo
,
512 sal_Int16 eFmt
= rInfo
.aFmt
.GetNumberingType();
513 if( (bEndNote
? SVX_NUM_ROMAN_LOWER
: SVX_NUM_ARABIC
) != eFmt
)
515 const sal_Char
*pStr
= SwHTMLWriter::GetNumFormat( eFmt
);
518 pParts
[0] = String::CreateFromAscii( pStr
);
522 if( rInfo
.nFtnOffset
> 0 )
524 pParts
[1] = String::CreateFromInt32( (sal_Int32
)rInfo
.nFtnOffset
);
527 if( rInfo
.GetPrefix().Len() > 0 )
529 pParts
[2] = rInfo
.GetPrefix();
532 if( rInfo
.GetSuffix().Len() > 0 )
534 pParts
[3] = rInfo
.GetSuffix();
541 void lcl_html_outFootEndNoteInfo( Writer
& rWrt
, String
*pParts
,
542 USHORT nParts
, const sal_Char
*pName
)
544 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
547 for( USHORT i
=0; i
<nParts
; i
++ )
550 String
aTmp( pParts
[i
] );
551 String
aRep( String::CreateFromAscii("\\\\") );
552 while( STRING_NOTFOUND
!= (nPos
= aTmp
.SearchAndReplaceAscii( "\\",
556 aRep
.AssignAscii( "\\;" );
557 while( STRING_NOTFOUND
!= (nPos
= aTmp
.SearchAndReplaceAscii( ";",
565 rHTMLWrt
.OutNewLine();
566 ByteString
sOut( '<' );
567 (((((((sOut
+= OOO_STRING_SVTOOLS_HTML_meta
) += ' ')
568 += OOO_STRING_SVTOOLS_HTML_O_name
) += "=\"") += pName
) += "\" ")
569 += OOO_STRING_SVTOOLS_HTML_O_content
) += "=\"";
570 rWrt
.Strm() << sOut
.GetBuffer();
571 HTMLOutFuncs::Out_String( rWrt
.Strm(), aContent
, rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
572 rWrt
.Strm() << "\">";
575 void SwHTMLWriter::OutFootEndNoteInfo()
577 // Nummerntyp (1 bzw. i)
587 const SwFtnInfo
& rInfo
= pDoc
->GetFtnInfo();
589 USHORT nParts
= lcl_html_fillEndNoteInfo( rInfo
, aParts
, FALSE
);
590 if( rInfo
.eNum
!= FTNNUM_DOC
)
592 aParts
[4] = rInfo
.eNum
== FTNNUM_CHAPTER
? 'C' : 'P';
595 if( rInfo
.ePos
!= FTNPOS_PAGE
)
600 if( rInfo
.aQuoVadis
.Len() > 0 )
602 aParts
[6] = rInfo
.aQuoVadis
;
605 if( rInfo
.aErgoSum
.Len() > 0 )
607 aParts
[7] = rInfo
.aErgoSum
;
611 lcl_html_outFootEndNoteInfo( *this, aParts
, nParts
,
612 OOO_STRING_SVTOOLS_HTML_META_sdfootnote
);
616 const SwEndNoteInfo
& rInfo
= pDoc
->GetEndNoteInfo();
618 USHORT nParts
= lcl_html_fillEndNoteInfo( rInfo
, aParts
, TRUE
);
620 lcl_html_outFootEndNoteInfo( *this, aParts
, nParts
,
621 OOO_STRING_SVTOOLS_HTML_META_sdendnote
);