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
->Insert( *pPam
, aFtn
, 0 );
233 (SwTxtFtn
*)pPam
->GetNode()->GetTxtNode()->GetTxtAttr(
234 pPam
->GetPoint()->nContent
.GetIndex() - 1,
236 // In Kopf- und Fusszeilen duerfen keine Fussnoten eingefuegt werden.
239 pFootEndNoteImpl
->aTxtFtns
.Insert( pTxtFtn
,
240 pFootEndNoteImpl
->aTxtFtns
.Count() );
242 pFootEndNoteImpl
->aNames
.Insert( new String(pFootEndNoteImpl
->sName
),
243 pFootEndNoteImpl
->aNames
.Count() );
245 pFootEndNoteImpl
->sName
= aEmptyStr
;
246 pFootEndNoteImpl
->sContent
= aEmptyStr
;
247 pFootEndNoteImpl
->bFixed
= FALSE
;
250 void SwHTMLParser::InsertFootEndNoteText()
252 if( pFootEndNoteImpl
&& pFootEndNoteImpl
->bFixed
)
253 pFootEndNoteImpl
->sContent
+= aToken
;
256 void SwHTMLParser::DeleteFootEndNoteImpl()
258 delete pFootEndNoteImpl
;
259 pFootEndNoteImpl
= 0;
262 SwNodeIndex
*SwHTMLParser::GetFootEndNoteSection( const String
& rName
)
264 SwNodeIndex
*pStartNodeIdx
= 0;
266 if( pFootEndNoteImpl
)
268 String
aName( rName
);
269 // TODO: ToUpperAscii
270 aName
.ToUpperAscii();
272 USHORT nCount
= pFootEndNoteImpl
->aNames
.Count();
273 for( USHORT i
=0; i
<nCount
; i
++ )
275 if( *pFootEndNoteImpl
->aNames
[i
] == aName
)
277 pStartNodeIdx
= pFootEndNoteImpl
->aTxtFtns
[i
]->GetStartNode();
278 pFootEndNoteImpl
->aNames
.DeleteAndDestroy( i
, 1 );
279 pFootEndNoteImpl
->aTxtFtns
.Remove( i
, 1 );
280 if( !pFootEndNoteImpl
->aNames
.Count() )
282 delete pFootEndNoteImpl
;
283 pFootEndNoteImpl
= 0;
291 return pStartNodeIdx
;
294 Writer
& OutHTML_SwFmtFtn( Writer
& rWrt
, const SfxPoolItem
& rHt
)
296 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
298 SwFmtFtn
& rFmtFtn
= (SwFmtFtn
&)rHt
;
299 SwTxtFtn
*pTxtFtn
= rFmtFtn
.GetTxtFtn();
303 String sFtnName
, sClass
;
305 if( rFmtFtn
.IsEndNote() )
307 nPos
= rHTMLWrt
.pFootEndNotes
? rHTMLWrt
.pFootEndNotes
->Count() : 0;
308 ASSERT( nPos
== rHTMLWrt
.nFootNote
+ rHTMLWrt
.nEndNote
,
309 "OutHTML_SwFmtFtn: Position falsch" );
310 sClass
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote_anc
);
311 sFtnName
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote
);
312 sFtnName
+= String::CreateFromInt32( (sal_Int32
)(++rHTMLWrt
.nEndNote
) );
316 nPos
= rHTMLWrt
.nFootNote
;
317 sClass
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote_anc
);
318 sFtnName
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote
);
319 sFtnName
+= String::CreateFromInt32( (sal_Int32
)(++rHTMLWrt
.nFootNote
));
322 if( !rHTMLWrt
.pFootEndNotes
)
323 rHTMLWrt
.pFootEndNotes
= new SwHTMLTxtFtns
;
324 rHTMLWrt
.pFootEndNotes
->Insert( pTxtFtn
, nPos
);
326 ByteString
sOut( '<' );
327 (((sOut
+= OOO_STRING_SVTOOLS_HTML_anchor
) += ' ') += OOO_STRING_SVTOOLS_HTML_O_class
) += "=\"";
328 rWrt
.Strm() << sOut
.GetBuffer();
329 HTMLOutFuncs::Out_String( rWrt
.Strm(), sClass
, rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
330 ((sOut
= "\" ") += OOO_STRING_SVTOOLS_HTML_O_name
) += "=\"";
331 rWrt
.Strm() << sOut
.GetBuffer();
332 HTMLOutFuncs::Out_String( rWrt
.Strm(), sFtnName
, rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
333 (((sOut
= OOO_STRING_SVTOOLS_HTML_FTN_anchor
) += "\" ") += OOO_STRING_SVTOOLS_HTML_O_href
) += "=\"#";
334 rWrt
.Strm() << sOut
.GetBuffer();
335 HTMLOutFuncs::Out_String( rWrt
.Strm(), sFtnName
, rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
336 (sOut
= OOO_STRING_SVTOOLS_HTML_FTN_symbol
)+= '\"';
337 if( rFmtFtn
.GetNumStr().Len() )
338 (sOut
+= ' ') += OOO_STRING_SVTOOLS_HTML_O_sdfixed
;
340 rWrt
.Strm() << sOut
.GetBuffer();
341 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_superscript
, TRUE
);
343 HTMLOutFuncs::Out_String( rWrt
.Strm(), rFmtFtn
.GetViewNumStr(*rWrt
.pDoc
),
344 rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
345 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_superscript
, FALSE
);
346 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), OOO_STRING_SVTOOLS_HTML_anchor
, FALSE
);
351 void SwHTMLWriter::OutFootEndNotes()
353 ASSERT( pFootEndNotes
,
354 "SwHTMLWriter::OutFootEndNotes(): unnoetiger Aufruf" );
359 USHORT nFtn
= nFootNote
, nEn
= nEndNote
;
361 nFootNote
= 0, nEndNote
= 0;
363 for( USHORT i
=0; i
<pFootEndNotes
->Count(); i
++ )
365 SwTxtFtn
*pTxtFtn
= (*pFootEndNotes
)[i
];
366 pFmtFtn
= &pTxtFtn
->GetFtn();
368 String sFtnName
, sClass
;
369 if( pFmtFtn
->IsEndNote() )
371 sClass
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote
);
372 sFtnName
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote
);
373 sFtnName
.Append( String::CreateFromInt32((sal_Int32
)(++nEndNote
)) );
377 sClass
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote
);
378 sFtnName
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote
);
379 sFtnName
.Append( String::CreateFromInt32((sal_Int32
)(++nFootNote
)));
384 ByteString
sOut( '<' );
385 (((sOut
+= OOO_STRING_SVTOOLS_HTML_division
) += ' ') += OOO_STRING_SVTOOLS_HTML_O_id
) += "=\"";
386 Strm() << sOut
.GetBuffer();
387 HTMLOutFuncs::Out_String( Strm(), sFtnName
, eDestEnc
, &aNonConvertableCharacters
);
391 IncIndentLevel(); // Inhalt von <DIV> einruecken
393 ASSERT( pTxtFtn
, "SwHTMLWriter::OutFootEndNotes: SwTxtFtn fehlt" );
394 SwNodeIndex
*pSttNdIdx
= pTxtFtn
->GetStartNode();
396 "SwHTMLWriter::OutFootEndNotes: StartNode-Index fehlt" );
399 HTMLSaveData
aSaveData( *this, pSttNdIdx
->GetIndex()+1,
400 pSttNdIdx
->GetNode().EndOfSectionIndex(), FALSE
);
401 Out_SwDoc( pCurPam
);
404 DecIndentLevel(); // Inhalt von <DIV> einruecken
407 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_division
, FALSE
);
411 "SwHTMLWriter::OutFootEndNotes: Ftn wurde nicht ausgegeben" );
414 if( pFmtFtn
->IsEndNote() )
424 ASSERT( nFtn
== nFootNote
,
425 "SwHTMLWriter::OutFootEndNotes: Anzahl Fussnoten stimmt nicht" );
426 ASSERT( nEn
== nEndNote
,
427 "SwHTMLWriter::OutFootEndNotes: Anzahl Endnoten stimmt nicht" );
430 delete pFootEndNotes
;
432 nFootNote
= nEndNote
= 0;
435 String
SwHTMLWriter::GetFootEndNoteSym( const SwFmtFtn
& rFmtFtn
)
437 const SwEndNoteInfo
* pInfo
= 0;
438 if( rFmtFtn
.GetNumStr().Len() == 0 )
439 pInfo
= rFmtFtn
.IsEndNote() ? &pDoc
->GetEndNoteInfo()
440 : &pDoc
->GetFtnInfo();
444 sRet
= pInfo
->GetPrefix();
445 sRet
+= rFmtFtn
.GetViewNumStr( *pDoc
);
447 sRet
+= pInfo
->GetSuffix();
452 void SwHTMLWriter::OutFootEndNoteSym( const SwFmtFtn
& rFmtFtn
,
456 const SwEndNoteInfo
*pInfo
;
458 String sFtnName
, sClass
, sPrefix
, sSuffix
;
459 if( rFmtFtn
.IsEndNote() )
461 sClass
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote_sym
);
462 sFtnName
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote
);
463 sFtnName
.Append( String::CreateFromInt32((sal_Int32
)nEndNote
) );
464 pInfo
= &pDoc
->GetEndNoteInfo();
468 sClass
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote_sym
);
469 sFtnName
.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote
);
470 sFtnName
.Append( String::CreateFromInt32((sal_Int32
)nFootNote
));
471 pInfo
= &pDoc
->GetFtnInfo();
474 const SwCharFmt
*pSymCharFmt
= pInfo
->GetCharFmt( *pDoc
);
475 if( pSymCharFmt
&& aScriptTextStyles
.Seek_Entry( (String
*)&pSymCharFmt
->GetName() ) )
479 case CSS1_OUTMODE_WESTERN
:
480 sClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-western") );
482 case CSS1_OUTMODE_CJK
:
483 sClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-cjk") );
485 case CSS1_OUTMODE_CTL
:
486 sClass
.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-ctl") );
491 ByteString
sOut( '<' );
492 (((sOut
+= OOO_STRING_SVTOOLS_HTML_anchor
) += ' ') += OOO_STRING_SVTOOLS_HTML_O_class
) += "=\"";
493 Strm() << sOut
.GetBuffer();
494 HTMLOutFuncs::Out_String( Strm(), sClass
, eDestEnc
, &aNonConvertableCharacters
);
495 ((sOut
= "\" ") += OOO_STRING_SVTOOLS_HTML_O_name
) += "=\"";
496 Strm() << sOut
.GetBuffer();
497 HTMLOutFuncs::Out_String( Strm(), sFtnName
, eDestEnc
, &aNonConvertableCharacters
);
498 (((sOut
= OOO_STRING_SVTOOLS_HTML_FTN_symbol
) +="\" ") += OOO_STRING_SVTOOLS_HTML_O_href
) += "=\"#";
499 Strm() << sOut
.GetBuffer();
500 HTMLOutFuncs::Out_String( Strm(), sFtnName
, eDestEnc
, &aNonConvertableCharacters
);
501 (sOut
= OOO_STRING_SVTOOLS_HTML_FTN_anchor
) += "\">";
502 Strm() << sOut
.GetBuffer();
504 HTMLOutFuncs::Out_String( Strm(), rNum
, eDestEnc
, &aNonConvertableCharacters
);
505 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_anchor
, FALSE
);
508 USHORT
lcl_html_fillEndNoteInfo( const SwEndNoteInfo
& rInfo
,
513 sal_Int16 eFmt
= rInfo
.aFmt
.GetNumberingType();
514 if( (bEndNote
? SVX_NUM_ROMAN_LOWER
: SVX_NUM_ARABIC
) != eFmt
)
516 const sal_Char
*pStr
= SwHTMLWriter::GetNumFormat( eFmt
);
519 pParts
[0] = String::CreateFromAscii( pStr
);
523 if( rInfo
.nFtnOffset
> 0 )
525 pParts
[1] = String::CreateFromInt32( (sal_Int32
)rInfo
.nFtnOffset
);
528 if( rInfo
.GetPrefix().Len() > 0 )
530 pParts
[2] = rInfo
.GetPrefix();
533 if( rInfo
.GetSuffix().Len() > 0 )
535 pParts
[3] = rInfo
.GetSuffix();
542 void lcl_html_outFootEndNoteInfo( Writer
& rWrt
, String
*pParts
,
543 USHORT nParts
, const sal_Char
*pName
)
545 SwHTMLWriter
& rHTMLWrt
= (SwHTMLWriter
&)rWrt
;
548 for( USHORT i
=0; i
<nParts
; i
++ )
551 String
aTmp( pParts
[i
] );
552 String
aRep( String::CreateFromAscii("\\\\") );
553 while( STRING_NOTFOUND
!= (nPos
= aTmp
.SearchAndReplaceAscii( "\\",
557 aRep
.AssignAscii( "\\;" );
558 while( STRING_NOTFOUND
!= (nPos
= aTmp
.SearchAndReplaceAscii( ";",
566 rHTMLWrt
.OutNewLine();
567 ByteString
sOut( '<' );
568 (((((((sOut
+= OOO_STRING_SVTOOLS_HTML_meta
) += ' ')
569 += OOO_STRING_SVTOOLS_HTML_O_name
) += "=\"") += pName
) += "\" ")
570 += OOO_STRING_SVTOOLS_HTML_O_content
) += "=\"";
571 rWrt
.Strm() << sOut
.GetBuffer();
572 HTMLOutFuncs::Out_String( rWrt
.Strm(), aContent
, rHTMLWrt
.eDestEnc
, &rHTMLWrt
.aNonConvertableCharacters
);
573 rWrt
.Strm() << "\">";
576 void SwHTMLWriter::OutFootEndNoteInfo()
578 // Nummerntyp (1 bzw. i)
588 const SwFtnInfo
& rInfo
= pDoc
->GetFtnInfo();
590 USHORT nParts
= lcl_html_fillEndNoteInfo( rInfo
, aParts
, FALSE
);
591 if( rInfo
.eNum
!= FTNNUM_DOC
)
593 aParts
[4] = rInfo
.eNum
== FTNNUM_CHAPTER
? 'C' : 'P';
596 if( rInfo
.ePos
!= FTNPOS_PAGE
)
601 if( rInfo
.aQuoVadis
.Len() > 0 )
603 aParts
[6] = rInfo
.aQuoVadis
;
606 if( rInfo
.aErgoSum
.Len() > 0 )
608 aParts
[7] = rInfo
.aErgoSum
;
612 lcl_html_outFootEndNoteInfo( *this, aParts
, nParts
,
613 OOO_STRING_SVTOOLS_HTML_META_sdfootnote
);
617 const SwEndNoteInfo
& rInfo
= pDoc
->GetEndNoteInfo();
619 USHORT nParts
= lcl_html_fillEndNoteInfo( rInfo
, aParts
, TRUE
);
621 lcl_html_outFootEndNoteInfo( *this, aParts
, nParts
,
622 OOO_STRING_SVTOOLS_HTML_META_sdendnote
);