/**************************************************************
 * 
 * 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
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"


#include <hintids.hxx>
#include <com/sun/star/i18n/ScriptType.hpp>
#include <vcl/svapp.hxx>
#include <vcl/wrkwin.hxx>
#include <tools/urlobj.hxx>
#include <sfx2/sfx.hrc>
#if !defined _SVSTDARR_XUB_STRLEN_DECL || !defined _SVSTDARR_USHORTS_DECL
#define _SVSTDARR_XUB_STRLEN
#define _SVSTDARR_USHORTS
#include <svl/svstdarr.hxx>
#endif
#include <svtools/htmlout.hxx>
#include <svtools/htmlkywd.hxx>
#include <svtools/htmltokn.h>
#include <svl/whiter.hxx>
#include <svx/htmlmode.hxx>
#include <editeng/escpitem.hxx>
#include <editeng/brkitem.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/udlnitem.hxx>
#include <editeng/crsditem.hxx>
#include <editeng/blnkitem.hxx>
#include <editeng/cmapitem.hxx>
#include <editeng/colritem.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/postitem.hxx>
#include <editeng/kernitem.hxx>
#include <editeng/wghtitem.hxx>
#include <editeng/lspcitem.hxx>
#include <editeng/adjitem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/brshitem.hxx>
#include <editeng/langitem.hxx>
#include <editeng/frmdiritem.hxx>
#include <fchrfmt.hxx>
#include <fmtautofmt.hxx>
#include <fmtfsize.hxx>
#include <fmtclds.hxx>
#include <fmtpdsc.hxx>
#include <fmtflcnt.hxx>
#include <fmtinfmt.hxx>
#include <fmtftn.hxx>
#include <txatbase.hxx>
#include <frmatr.hxx>
#include <charfmt.hxx>
#include <fmtfld.hxx>
#include <doc.hxx>
#include <pam.hxx>
#include <ndtxt.hxx>
#include <paratr.hxx>
#include <poolfmt.hxx>
#include <pagedesc.hxx>
#include <swtable.hxx>
#include "fldbas.hxx"
#include <breakit.hxx>
#include <htmlnum.hxx>
#include <wrthtml.hxx>
#include <htmlfly.hxx>
#include <numrule.hxx>

using namespace ::com::sun::star;

/*
 * um nicht immer wieder nach einem Update festzustellen, das irgendwelche
 * Hint-Ids dazugekommen sind, wird hier definiert, die Groesse der Tabelle
 * definiert und mit der akt. verglichen. Bei unterschieden wird der
 * Compiler schon meckern.
 *
 * diese Section und die dazugeherigen Tabellen muessen in folgenden Files
 * gepflegt werden: rtf\rtfatr.cxx, sw6\sw6atr.cxx, w4w\w4watr.cxx
 */
#if !defined(UNX) && !defined(MSC) && !defined(PPC) && !defined(CSET) && !defined(__MWERKS__) && !defined(WTC) && !defined(__MINGW32__) && !defined(OS2)

#define ATTRFNTAB_SIZE 130
#if ATTRFNTAB_SIZE != POOLATTR_END - POOLATTR_BEGIN
#error Attribut-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
#endif

#ifdef FORMAT_TABELLE
// da sie nicht benutzt wird!
#define FORMATTAB_SIZE 7
#if FORMATTAB_SIZE != RES_FMT_END - RES_FMT_BEGIN
#error Format-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
#endif
#endif

#define NODETAB_SIZE 3
#if NODETAB_SIZE != RES_NODE_END - RES_NODE_BEGIN
#error Node-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
#endif

#endif

#define HTML_BULLETCHAR_DISC	34
#define HTML_BULLETCHAR_CIRCLE	38
#define HTML_BULLETCHAR_SQUARE	36

#define COLFUZZY 20

//-----------------------------------------------------------------------

HTMLOutEvent __FAR_DATA aAnchorEventTable[] =
{
	{ OOO_STRING_SVTOOLS_HTML_O_SDonclick,		OOO_STRING_SVTOOLS_HTML_O_onclick,		SFX_EVENT_MOUSECLICK_OBJECT	},
	{ OOO_STRING_SVTOOLS_HTML_O_SDonmouseover,	OOO_STRING_SVTOOLS_HTML_O_onmouseover,	SFX_EVENT_MOUSEOVER_OBJECT	},
	{ OOO_STRING_SVTOOLS_HTML_O_SDonmouseout,		OOO_STRING_SVTOOLS_HTML_O_onmouseout,		SFX_EVENT_MOUSEOUT_OBJECT	},
	{ 0,						0,					  	0							}
};

static Writer& OutHTML_SvxAdjust( Writer& rWrt, const SfxPoolItem& rHt );

static Writer& OutHTML_HoriSpacer( Writer& rWrt, sal_Int16 nSize )
{
	ASSERT( nSize>0, "horizontaler SPACER mit negativem Wert?" )
	if( nSize <= 0 )
		return rWrt;

	if( Application::GetDefaultDevice() )
	{
		nSize = (sal_Int16)Application::GetDefaultDevice()
			->LogicToPixel( Size(nSize,0), MapMode(MAP_TWIP) ).Width();
	}

	ByteString sOut( '<' );
	(((((((((sOut += OOO_STRING_SVTOOLS_HTML_spacer)
		+= ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += '=') += OOO_STRING_SVTOOLS_HTML_SPTYPE_horizontal)
		+= ' ') += OOO_STRING_SVTOOLS_HTML_O_size) += '=')
						+=ByteString::CreateFromInt32(nSize)) += '>';

	rWrt.Strm() << sOut.GetBuffer();

	return rWrt;
}

sal_uInt16 SwHTMLWriter::GetDefListLvl( const String& rNm, sal_uInt16 nPoolId )
{
	if( nPoolId == RES_POOLCOLL_HTML_DD )
	{
		return 1 | HTML_DLCOLL_DD;
	}
	else if( nPoolId == RES_POOLCOLL_HTML_DT )
	{
		return 1 | HTML_DLCOLL_DT;
	}

	String sDTDD( String::CreateFromAscii(OOO_STRING_SVTOOLS_HTML_dt) );
	sDTDD += ' ';
	if( COMPARE_EQUAL == sDTDD.CompareTo( rNm, sDTDD.Len() ) )
		// DefinitionList - term
		return (sal_uInt16)rNm.Copy( sDTDD.Len() ).ToInt32() | HTML_DLCOLL_DT;

	sDTDD.AssignAscii( OOO_STRING_SVTOOLS_HTML_dd );
	sDTDD += ' ';
	if( COMPARE_EQUAL == sDTDD.CompareTo( rNm, sDTDD.Len() ) )
		// DefinitionList - definition
		return (sal_uInt16)rNm.Copy( sDTDD.Len() ).ToInt32() | HTML_DLCOLL_DD;

	return 0;
}

void SwHTMLWriter::OutAndSetDefList( sal_uInt16 nNewLvl )
{
	// eventuell muss erst mal eine Liste aufgemacht werden
	if( nDefListLvl < nNewLvl )
	{
		// output </pre> for the previous(!) pararagraph, if required.
		// Preferable, the <pre> is exported by OutHTML_SwFmtOff for the
	   	// previous	paragraph already, but that's not possible, because a very
		// deep look at the next paragraph (this one) is required to figure
		// out that a def list starts here.

		ChangeParaToken( 0 );

		// entsprechend dem Level-Unterschied schreiben!
		for( sal_uInt16 i=nDefListLvl; i<nNewLvl; i++ )
		{
			if( bLFPossible )
				OutNewLine();
			HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_deflist, sal_True );
			IncIndentLevel();
			bLFPossible = sal_True;
		}
	}
	else if( nDefListLvl > nNewLvl )
	{
		for( sal_uInt16 i=nNewLvl ; i < nDefListLvl; i++ )
		{
			DecIndentLevel();
			if( bLFPossible )
				OutNewLine();
			HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_deflist, sal_False );
			bLFPossible = sal_True;
		}
	}

	nDefListLvl = nNewLvl;
}


void SwHTMLWriter::ChangeParaToken( sal_uInt16 nNew )
{
	if( nNew != nLastParaToken && HTML_PREFORMTXT_ON == nLastParaToken )
	{
		HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_preformtxt, sal_False );
		bLFPossible = sal_True;
	}
	nLastParaToken = nNew;
}

sal_uInt16 SwHTMLWriter::GetCSS1ScriptForScriptType( sal_uInt16 nScriptType )
{
	sal_uInt16 nRet = CSS1_OUTMODE_ANY_SCRIPT;

	switch( nScriptType )
	{
    case i18n::ScriptType::LATIN:
		nRet = CSS1_OUTMODE_WESTERN;
		break;
    case i18n::ScriptType::ASIAN:
		nRet = CSS1_OUTMODE_CJK;
		break;
    case i18n::ScriptType::COMPLEX:
		nRet = CSS1_OUTMODE_CTL;
		break;
	}

	return nRet;
}

// fuer die Formate muesste eine einzige Ausgabe-Funktion genuegen !
/*
 * Formate wie folgt ausgeben:
 * - fuer Formate, fuer die es entsprechende HTML-Tags gibt wird das
 *   Tag ausgegeben
 * - fuer alle anderen wird ein Absatz-Tag <P> ausgegeben und bUserFmt
 *   gesetzt
 * - Wenn eine Absatz-Ausrichtung am uebergebenen Item-Set des Nodes
 *   oder im Item-Set des Format gesetzt ist, wird ein ALIGN=xxx ausgegeben,
 *   sofern HTML es zulaesst
 * - in jedem Fall wird harte Attributierung als STYLE-Option geschrieben.
 *   Wenn bUserFmt nicht gesetzt ist, wird nur der uebergebene Item-Set
 *   betrachtet. Sonst werden auch Attribute des Formats ausgegeben.
 */

struct SwHTMLTxtCollOutputInfo
{
	ByteString aToken;				// auszugendens End-Token
	SfxItemSet *pItemSet;		// harte Attributierung

	sal_Bool bInNumBulList;			// in einer Aufzaehlungs-Liste;
	sal_Bool bParaPossible;			// ein </P> darf zusaetzlich ausgegeben werden
	sal_Bool bOutPara;				// ein </P> soll ausgegeben werden
	sal_Bool bOutDiv;				// write a </DIV>

	SwHTMLTxtCollOutputInfo() :
		pItemSet( 0 ),
		bInNumBulList( sal_False ),
		bParaPossible( sal_False ),
		bOutPara( sal_False ),
		bOutDiv( sal_False )
	{}

	~SwHTMLTxtCollOutputInfo();

	sal_Bool HasParaToken() const { return aToken.Len()==1 && aToken.GetChar(0)=='P'; }
	sal_Bool ShouldOutputToken() const { return bOutPara || !HasParaToken(); }
};

SwHTMLTxtCollOutputInfo::~SwHTMLTxtCollOutputInfo()
{
	delete pItemSet;
}

struct SwHTMLFmtInfo
{
	const SwFmt *pFmt;		// das Format selbst
	const SwFmt *pRefFmt;	// das Vergleichs-Format

	ByteString aToken;			// das auszugebende Token
	String aClass;			// die auszugebende Klasse

	SfxItemSet *pItemSet;	// der auszugebende Attribut-Set

	sal_Int32 nLeftMargin;		// ein par default-Werte fuer
	sal_Int32 nRightMargin;	// Absatz-Vorlagen
	short nFirstLineIndent;

	sal_uInt16 nTopMargin;
	sal_uInt16 nBottomMargin;

	sal_Bool bScriptDependent;

	// Konstruktor fuer einen Dummy zum Suchen
	SwHTMLFmtInfo( const SwFmt *pF ) :
		pFmt( pF ), pItemSet( 0 )
	{}


	// Konstruktor zum Erstellen der Format-Info
	SwHTMLFmtInfo( const SwFmt *pFmt, SwDoc *pDoc, SwDoc *pTemlate,
				   sal_Bool bOutStyles, LanguageType eDfltLang=LANGUAGE_DONTKNOW,
				   sal_uInt16 nScript=CSS1_OUTMODE_ANY_SCRIPT,
				   sal_Bool bHardDrop=sal_False );
	~SwHTMLFmtInfo();

	friend sal_Bool operator==( const SwHTMLFmtInfo& rInfo1,
							const SwHTMLFmtInfo& rInfo2 )
	{
		return (long)rInfo1.pFmt == (long)rInfo2.pFmt;
	}

	friend sal_Bool operator<( const SwHTMLFmtInfo& rInfo1,
							const SwHTMLFmtInfo& rInfo2 )
	{
		return (long)rInfo1.pFmt < (long)rInfo2.pFmt;
	}

};

SV_IMPL_OP_PTRARR_SORT( SwHTMLFmtInfos, SwHTMLFmtInfo* )

SwHTMLFmtInfo::SwHTMLFmtInfo( const SwFmt *pF, SwDoc *pDoc, SwDoc *pTemplate,
							  sal_Bool bOutStyles,
							  LanguageType eDfltLang,
							  sal_uInt16 nCSS1Script, sal_Bool bHardDrop ) :
	pFmt( pF ), pItemSet( 0 ), bScriptDependent( sal_False )
{
	sal_uInt16 nRefPoolId = 0;
	// Den Selektor des Formats holen
	sal_uInt16 nDeep = SwHTMLWriter::GetCSS1Selector( pFmt, aToken, aClass,
												  nRefPoolId );
	ASSERT( nDeep ? aToken.Len()>0 : aToken.Len()==0,
			"Hier stimmt doch was mit dem Token nicht!" );
	ASSERT( nDeep ? nRefPoolId : !nRefPoolId,
			"Hier stimmt doch was mit der Vergleichs-Vorlage nicht!" );

	sal_Bool bTxtColl = pFmt->Which() == RES_TXTFMTCOLL ||
					pFmt->Which() == RES_CONDTXTFMTCOLL;

	const SwFmt *pReferenceFmt = 0;	// Vergleichs-Format
	sal_Bool bSetDefaults = sal_True, bClearSame = sal_True;
	if( nDeep != 0 )
	{
		// Es ist eine HTML-Tag-Vorlage oder die Vorlage ist von einer
		// solchen abgeleitet
		if( !bOutStyles )
		{
			// wenn keine Styles exportiert werden, muss evtl. zusaetlich
			// harte Attributierung geschrieben werden
			switch( nDeep )
			{
			case CSS1_FMT_ISTAG:
			case CSS1_FMT_CMPREF:
				// fuer HTML-Tag-Vorlagen die Unterscheide zum Original
				// (sofern verfuegbar)
				pReferenceFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId,
														pTemplate );
				break;

			default:
				// sonst die zur HTML-Tag-Vorlage des Originals oder des
				// aktuellen Doks, wenn die nicht verfuegbar ist
				if( pTemplate )
					pReferenceFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId,
															pTemplate );
				else
					pReferenceFmt = SwHTMLWriter::GetParentFmt( *pFmt, nDeep );
				break;
			}
		}
	}
	else if( bTxtColl )
	{
		// Nicht von einer HTML-Tag-Vorlage abgeleitete Absatz-Vorlagen
		// muessen als harte Attributierung relativ zur Textkoerper-Volage
		// exportiert werden. Fuer Nicht-Styles-Export sollte die der
		// HTML-Vorlage als Referenz dienen
		if( !bOutStyles && pTemplate )
            pReferenceFmt = pTemplate->GetTxtCollFromPool( RES_POOLCOLL_TEXT, false );
		else
            pReferenceFmt = pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT, false );
	}

	if( pReferenceFmt || nDeep==0 )
	{
		pItemSet = new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
							   		pFmt->GetAttrSet().GetRanges() );
		// wenn Unterschiede zu einer anderen Vorlage geschrieben werden
		// sollen ist harte Attributierung noetig. Fuer Vorlagen, die
		// nicht von HTML-Tag-Vorlagen abgeleitet sind, gilt das immer

		pItemSet->Set( pFmt->GetAttrSet(), sal_True );

		if( pReferenceFmt )
			SwHTMLWriter::SubtractItemSet( *pItemSet, pReferenceFmt->GetAttrSet(),
										   bSetDefaults, bClearSame );

		// einen leeren Item-Set gleich loeschen, das spart speater
		// Arbeit
		if( !pItemSet->Count() )
		{
			delete pItemSet;
			pItemSet = 0;
		}
	}

	if( bTxtColl )
	{
		if( bOutStyles )
		{
			// We have to add hard attributes for any script dependent
			// item that is not accessed by the style
			static sal_uInt16 aWhichIds[3][4] =
			{
				{ RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
					RES_CHRATR_POSTURE, RES_CHRATR_WEIGHT },
				{ RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONTSIZE,
					RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT },
				{ RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONTSIZE,
					RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT }
			};

			sal_uInt16 nRef = 0;
			sal_uInt16 aSets[2] = {0,0};
			switch( nCSS1Script )
			{
			case CSS1_OUTMODE_WESTERN:
				nRef = 0;
				aSets[0] = 1;
				aSets[1] = 2;
				break;
			case CSS1_OUTMODE_CJK:
				nRef = 1;
				aSets[0] = 0;
				aSets[1] = 2;
				break;
			case CSS1_OUTMODE_CTL:
				nRef = 2;
				aSets[0] = 0;
				aSets[1] = 1;
				break;
			}
			for( sal_uInt16 i=0; i<4; i++ )
			{
                const SfxPoolItem& rRef = pFmt->GetFmtAttr( aWhichIds[nRef][i] );
				for( sal_uInt16 j=0; j<2; j++ )
				{
                    const SfxPoolItem& rSet = pFmt->GetFmtAttr( aWhichIds[aSets[j]][i] );
					if( rSet != rRef )
					{
						if( !pItemSet )
							pItemSet = new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
													   pFmt->GetAttrSet().GetRanges() );
						pItemSet->Put( rSet );
					}
				}
			}
		}

		// Ggf. noch ein DropCap-Attribut uebernehmen
		if( bOutStyles && bHardDrop && nDeep != 0 )
		{
			const SfxPoolItem *pItem;
			if( SFX_ITEM_SET==pFmt->GetAttrSet().GetItemState(
									RES_PARATR_DROP, sal_True, &pItem ) )
			{
				sal_Bool bPut = sal_True;
				if( pTemplate )
				{
					pReferenceFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pTemplate );
					const SfxPoolItem *pRefItem;
					sal_Bool bRefItemSet =
						SFX_ITEM_SET==pReferenceFmt->GetAttrSet().GetItemState(
										RES_PARATR_DROP, sal_True, &pRefItem );
					bPut = !bRefItemSet || *pItem!=*pRefItem;
				}
				if( bPut )
				{
					if( !pItemSet )
						pItemSet = new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
												   pFmt->GetAttrSet().GetRanges() );
					pItemSet->Put( *pItem );
				}
			}
		}


		// Die diversen default-Abstaende aus der Vorlage oder der
		// Vergleischs-Vorlage merken
		const SvxLRSpaceItem &rLRSpace =
			(pReferenceFmt ? pReferenceFmt : pFmt)->GetLRSpace();
		nLeftMargin = rLRSpace.GetTxtLeft();
		nRightMargin = rLRSpace.GetRight();
		nFirstLineIndent = rLRSpace.GetTxtFirstLineOfst();

		const SvxULSpaceItem &rULSpace =
			(pReferenceFmt ? pReferenceFmt : pFmt)->GetULSpace();
		nTopMargin = rULSpace.GetUpper();
		nBottomMargin = rULSpace.GetLower();

		// export language if it differs from the default language
		sal_uInt16 nWhichId =
			SwHTMLWriter::GetLangWhichIdFromScript( nCSS1Script );
		const SvxLanguageItem& rLang =
            (const SvxLanguageItem&)pFmt->GetFmtAttr( nWhichId );
		LanguageType eLang = rLang.GetLanguage();
		if( eLang != eDfltLang )
		{
			if( !pItemSet )
				pItemSet = new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
										   pFmt->GetAttrSet().GetRanges() );
			pItemSet->Put( rLang );
		}

		static sal_uInt16 aWhichIds[3] =
			{ RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE,
				RES_CHRATR_CTL_LANGUAGE };
		for( sal_uInt16 i=0; i<3; i++ )
		{
			if( aWhichIds[i] != nWhichId )
			{
				const SvxLanguageItem& rTmpLang =
                    (const SvxLanguageItem&)pFmt->GetFmtAttr(aWhichIds[i]);
				if( rTmpLang.GetLanguage() != eLang )
				{
					if( !pItemSet )
						pItemSet = new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
												   pFmt->GetAttrSet().GetRanges() );
					pItemSet->Put( rTmpLang );
				}
			}
		}
	}
}

SwHTMLFmtInfo::~SwHTMLFmtInfo()
{
	delete pItemSet;
}

void OutHTML_SwFmt( Writer& rWrt, const SwFmt& rFmt,
					const SfxItemSet *pNodeItemSet,
					SwHTMLTxtCollOutputInfo& rInfo )
{
	ASSERT( RES_CONDTXTFMTCOLL==rFmt.Which() || RES_TXTFMTCOLL==rFmt.Which(),
			"keine Absatz-Vorlage" );

	SwHTMLWriter & rHWrt = (SwHTMLWriter&)rWrt;

	// Erstmal ein par Flags ...
	sal_uInt16 nNewDefListLvl = 0;
	sal_uInt16 nNumStart = USHRT_MAX;
	sal_Bool bForceDL = sal_False;
	sal_Bool bDT = sal_False;
	rInfo.bInNumBulList = sal_False;  	// Wir sind in einer Liste?
	sal_Bool bNumbered = sal_False;			// Der aktuelle Absatz ist numeriert
	sal_Bool bPara = sal_False;				// das aktuelle Token ist <P>
	rInfo.bParaPossible = sal_False;	// ein <P> darf zusaetzlich ausgegeben werden
	sal_Bool bNoEndTag = sal_False;			// kein End-Tag ausgeben

	rHWrt.bNoAlign = sal_False;			// kein ALIGN=... moeglich
	sal_Bool bNoStyle = sal_False;			// kein STYLE=... moeglich
	sal_uInt8 nBulletGrfLvl = 255;	  	// Die auszugebende Bullet-Grafik

	// Sind wir in einer Aufzaehlungs- oder Numerierungliste?
	const SwTxtNode* pTxtNd = rWrt.pCurPam->GetNode()->GetTxtNode();

	SwHTMLNumRuleInfo aNumInfo;
	if( rHWrt.GetNextNumInfo() )
	{
		aNumInfo = *rHWrt.GetNextNumInfo();
		rHWrt.ClearNextNumInfo();
	}
	else
	{
		aNumInfo.Set( *pTxtNd );
	}

	if( aNumInfo.GetNumRule() )
	{
		rInfo.bInNumBulList = sal_True;
		nNewDefListLvl = 0;

		// ist der aktuelle Absatz numeriert?
		bNumbered = aNumInfo.IsNumbered();
		sal_uInt8 nLvl = aNumInfo.GetLevel();

        ASSERT( pTxtNd->GetActualListLevel() == nLvl,
				"Gemerkter Num-Level ist falsch" );
        ASSERT( bNumbered == static_cast< sal_Bool >(pTxtNd->IsCountedInList()),
				"Gemerkter Numerierungs-Zustand ist falsch" );

		if( bNumbered )
		{
			nBulletGrfLvl = nLvl; // nur veruebergehend!!!
            // --> OD 2005-11-15 #i57919#
            // correction of re-factoring done by cws swnumtree:
            // - <nNumStart> has to contain the restart value, if the
            //   numbering is restarted at this text node. Value <USHRT_MAX>
            //   indicates, that no additional restart value has to be written.
            if ( pTxtNd->IsListRestart() )
            {
                nNumStart = static_cast< sal_uInt16 >(pTxtNd->GetActualListStartValue());
            }
            // <--
			DBG_ASSERT( rHWrt.nLastParaToken == 0,
				"<PRE> wurde nicht vor <LI> beendet." );
		}
	}

	// Jetzt holen wir das Token und ggf. die Klasse
	SwHTMLFmtInfo aFmtInfo( &rFmt );
	sal_uInt16 nArrayPos;
	const SwHTMLFmtInfo *pFmtInfo;
	if( rHWrt.aTxtCollInfos.Seek_Entry( &aFmtInfo, &nArrayPos ) )
	{
		pFmtInfo = rHWrt.aTxtCollInfos[nArrayPos];
	}
	else
	{
		pFmtInfo = new SwHTMLFmtInfo( &rFmt, rWrt.pDoc, rHWrt.pTemplate,
									  rHWrt.bCfgOutStyles, rHWrt.eLang,
									  rHWrt.nCSS1Script,
									  !rHWrt.IsHTMLMode(HTMLMODE_DROPCAPS) );
		rHWrt.aTxtCollInfos.C40_PTR_INSERT( SwHTMLFmtInfo, pFmtInfo );
		String aName( rFmt.GetName() );
		if( rHWrt.aScriptParaStyles.Seek_Entry( &aName ) )
			((SwHTMLFmtInfo *)pFmtInfo)->bScriptDependent = sal_True;
	}

	// Jetzt wird festgelegt, was aufgrund des Tokens so moeglich ist
	sal_uInt16 nToken = 0;			// Token fuer Tag-Wechsel
	sal_Bool bOutNewLine = sal_False;	// nur ein LF ausgeben?
	if( pFmtInfo->aToken.Len() )
	{
		// Es ist eine HTML-Tag-Vorlage oder die Vorlage ist von einer
		// solchen abgeleitet
		rInfo.aToken = pFmtInfo->aToken;

		// der erste Buchstabe reicht meistens
		switch( rInfo.aToken.GetChar( 0 ) )
		{
		case 'A':	ASSERT( rInfo.aToken.Equals(OOO_STRING_SVTOOLS_HTML_address),
							"Doch kein ADDRESS?" );
					rInfo.bParaPossible = sal_True;
					rHWrt.bNoAlign = sal_True;
					break;

		case 'B':	ASSERT( rInfo.aToken.Equals(OOO_STRING_SVTOOLS_HTML_blockquote),
							"Doch kein BLOCKQUOTE?" );
					rInfo.bParaPossible = sal_True;
					rHWrt.bNoAlign = sal_True;
					break;

		case 'P':	if( rInfo.aToken.Len() == 1 )
					{
						bPara = sal_True;
					}
					else
					{
						ASSERT( rInfo.aToken.Equals(OOO_STRING_SVTOOLS_HTML_preformtxt),
								"Doch kein PRE?" );
						if( HTML_PREFORMTXT_ON == rHWrt.nLastParaToken )
						{
							bOutNewLine = sal_True;
						}
						else
						{
							nToken = HTML_PREFORMTXT_ON;
							rHWrt.bNoAlign = sal_True;
							bNoEndTag = sal_True;
						}
					}
					break;

		case 'D':	ASSERT( rInfo.aToken.Equals(OOO_STRING_SVTOOLS_HTML_dt) ||
							rInfo.aToken.Equals(OOO_STRING_SVTOOLS_HTML_dd),
							"Doch kein DD/DT?" );
					bDT = rInfo.aToken.Equals(OOO_STRING_SVTOOLS_HTML_dt);
					rInfo.bParaPossible = !bDT;
					rHWrt.bNoAlign = sal_True;
					bForceDL = sal_True;
					break;
		}
	}
	else
	{
		// alle Vorlagen, die nicht einem HTML-Tag entsprechen oder von
		// diesem abgeleitet sind, werden als <P> exportiert

		rInfo.aToken = OOO_STRING_SVTOOLS_HTML_parabreak;
		bPara = sal_True;
	}

	// Falls noetig, die harte Attributierung der Vorlage uebernehmen
	if( pFmtInfo->pItemSet )
	{
		ASSERT( !rInfo.pItemSet, "Wo kommt der Item-Set her?" );
		rInfo.pItemSet = new SfxItemSet( *pFmtInfo->pItemSet );
	}

	// und noch die harte Attributierung des Absatzes dazunehmen
	if( pNodeItemSet )
	{
		if( rInfo.pItemSet )
			rInfo.pItemSet->Put( *pNodeItemSet );
		else
			rInfo.pItemSet = new SfxItemSet( *pNodeItemSet );
	}

	// den unteren Absatz-Abstand brauchen wir noch
	const SvxULSpaceItem& rULSpace =
		pNodeItemSet ? ((const SvxULSpaceItem &)pNodeItemSet->Get(RES_UL_SPACE))
					 : rFmt.GetULSpace();


	if( (rHWrt.bOutHeader &&
		 rWrt.pCurPam->GetPoint()->nNode.GetIndex() ==
			rWrt.pCurPam->GetMark()->nNode.GetIndex()) ||
		 rHWrt.bOutFooter )
	{
		if( rHWrt.bCfgOutStyles )
		{
			SvxULSpaceItem aULSpaceItem( rULSpace );
			if( rHWrt.bOutHeader )
				aULSpaceItem.SetLower( rHWrt.nHeaderFooterSpace );
			else
				aULSpaceItem.SetUpper( rHWrt.nHeaderFooterSpace );

			if( !rInfo.pItemSet )
				rInfo.pItemSet = new SfxItemSet(
									*rFmt.GetAttrSet().GetPool(),
									RES_UL_SPACE, RES_UL_SPACE );
			rInfo.pItemSet->Put( aULSpaceItem );
		}
		rHWrt.bOutHeader = sal_False;
		rHWrt.bOutFooter = sal_False;
	}

	if( bOutNewLine )
	{
		// nur einen Zeilen-Umbruch (ohne Einrueckung) am Absatz-Anfang
		// ausgeben
		rInfo.aToken.Erase();	// kein End-Tag ausgeben
		rWrt.Strm() << SwHTMLWriter::sNewLine;

		return;
	}


	// soll ein ALIGN=... geschrieben werden?
	const SfxPoolItem* pAdjItem = 0;
	const SfxPoolItem* pItem;

	if( rInfo.pItemSet &&
		SFX_ITEM_SET == rInfo.pItemSet->GetItemState( RES_PARATR_ADJUST,
													  sal_False, &pItem ) )
	{
		pAdjItem = pItem;
	}

	// Unteren Absatz-Abstand beachten ? (nie im letzen Absatz von
	// Tabellen)
	sal_Bool bUseParSpace =	!rHWrt.bOutTable ||
						(rWrt.pCurPam->GetPoint()->nNode.GetIndex() !=
						 rWrt.pCurPam->GetMark()->nNode.GetIndex());
	// Wenn Styles exportiert werden, wird aus eingerueckten Absaetzen
	// eine Definitions-Liste
	const SvxLRSpaceItem& rLRSpace =
		pNodeItemSet ? ((const SvxLRSpaceItem &)pNodeItemSet->Get(RES_LR_SPACE))
					 : rFmt.GetLRSpace();
	if( (!rHWrt.bCfgOutStyles || bForceDL) && !rInfo.bInNumBulList )
	{
		sal_Int32 nLeftMargin;
		if( bForceDL )
			nLeftMargin = rLRSpace.GetTxtLeft();
		else
			nLeftMargin = rLRSpace.GetTxtLeft() > pFmtInfo->nLeftMargin
				? rLRSpace.GetTxtLeft() - pFmtInfo->nLeftMargin
				: 0;

		if( nLeftMargin > 0 && rHWrt.nDefListMargin > 0 )
		{
            nNewDefListLvl = static_cast< sal_uInt16 >((nLeftMargin + (rHWrt.nDefListMargin/2)) /
                                                    rHWrt.nDefListMargin);
			if( nNewDefListLvl == 0 && bForceDL && !bDT )
				nNewDefListLvl = 1;
		}
		else
		{
			// If the left margin is 0 or negative, emulating indent
			// with <dd> does not work. We then set a def list only if
			// the dd style is used.
			nNewDefListLvl = (bForceDL&& !bDT) ? 1 : 0;
		}

		sal_Bool bIsNextTxtNode =
			rWrt.pDoc->GetNodes()[rWrt.pCurPam->GetPoint()->nNode.GetIndex()+1]
					 ->IsTxtNode();

		if( bForceDL && bDT )
		{
			// Statt eines DD muessen wir hier auch ein DT der Ebene
			// darueber nehmen
			nNewDefListLvl++;
		}
		else if( !nNewDefListLvl && !rHWrt.bCfgOutStyles && bPara &&
				 rULSpace.GetLower()==0 &&
				 ((bUseParSpace && bIsNextTxtNode) || rHWrt.nDefListLvl==1) &&
				 (!pAdjItem || SVX_ADJUST_LEFT==
					((const SvxAdjustItem *)pAdjItem)->GetAdjust()) )
		{
			// Absaetze ohne unteren Abstand als DT exportieren
			nNewDefListLvl = 1;
			bDT = sal_True;
			rInfo.bParaPossible = sal_False;
			rHWrt.bNoAlign = sal_True;
		}
	}

	if( nNewDefListLvl != rHWrt.nDefListLvl )
		rHWrt.OutAndSetDefList( nNewDefListLvl );

	// ggf. eine Aufzaehlung- oder Numerierungsliste beginnen
	if( rInfo.bInNumBulList )
	{
		ASSERT( !rHWrt.nDefListLvl, "DL in OL geht nicht!" );
		OutHTML_NumBulListStart( rHWrt, aNumInfo );

		if( bNumbered )
		{
			if( rHWrt.aBulletGrfs[nBulletGrfLvl].Len()  )
				bNumbered = sal_False;
			else
				nBulletGrfLvl = 255;
		}
	}

	// Die Defaults aus der Vorlage merken, denn sie muessen nicht
	// exportiert werden
	rHWrt.nDfltLeftMargin = pFmtInfo->nLeftMargin;
	rHWrt.nDfltRightMargin = pFmtInfo->nRightMargin;
	rHWrt.nDfltFirstLineIndent = pFmtInfo->nFirstLineIndent;

	if( rInfo.bInNumBulList )
	{
		if( !rHWrt.IsHTMLMode( HTMLMODE_LSPACE_IN_NUMBUL ) )
			rHWrt.nDfltLeftMargin = rLRSpace.GetTxtLeft();

		// In Numerierungs-Listen keinen Ertzeilen-Einzug ausgeben.
		rHWrt.nFirstLineIndent = rLRSpace.GetTxtFirstLineOfst();
	}

	if( rInfo.bInNumBulList && bNumbered && bPara && !rHWrt.bCfgOutStyles )
	{
		// ein einzelnes LI hat keinen Abstand
		rHWrt.nDfltTopMargin = 0;
		rHWrt.nDfltBottomMargin = 0;
	}
	else if( rHWrt.nDefListLvl && bPara )
	{
		// ein einzelnes DD hat auch keinen Abstand
		rHWrt.nDfltTopMargin = 0;
		rHWrt.nDfltBottomMargin = 0;
	}
	else
	{
		rHWrt.nDfltTopMargin = pFmtInfo->nTopMargin;
		// #60393#: Wenn im letzten Absatz einer Tabelle der
		// untere Absatz-Abstand veraendert wird, vertut sich
		// Netscape total. Deshalb exportieren wir hier erstmal
		// nichts, indem wir den Abstand aus dem Absatz als Default
		// setzen.
		if( rHWrt.bCfgNetscape4 && !bUseParSpace )
			rHWrt.nDfltBottomMargin = rULSpace.GetLower();
		else
			rHWrt.nDfltBottomMargin = pFmtInfo->nBottomMargin;
	}

	if( rHWrt.nDefListLvl )
	{
		rHWrt.nLeftMargin =
			(rHWrt.nDefListLvl-1) * rHWrt.nDefListMargin;
	}

	if( rHWrt.bLFPossible )
		rHWrt.OutNewLine(); // Absatz-Tag in neue Zeile
	rInfo.bOutPara = sal_False;

	// das ist jetzt unser neues Token
	rHWrt.ChangeParaToken( nToken );

	sal_Bool bHasParSpace = bUseParSpace && rULSpace.GetLower() > 0;

	// ggf ein List-Item aufmachen
	if( rInfo.bInNumBulList && bNumbered )
	{
		ByteString sOut( '<' );
		sOut += OOO_STRING_SVTOOLS_HTML_li;
		if( USHRT_MAX != nNumStart )
			(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_value) += '=')
				+= ByteString::CreateFromInt32(nNumStart);
		sOut += '>';
		rWrt.Strm() << sOut.GetBuffer();
	}

	if( rHWrt.nDefListLvl > 0 && !bForceDL )
	{
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), bDT ? OOO_STRING_SVTOOLS_HTML_dt : OOO_STRING_SVTOOLS_HTML_dd );
	}

	if( pAdjItem &&
		rHWrt.IsHTMLMode( HTMLMODE_NO_CONTROL_CENTERING ) &&
		rHWrt.HasControls() )
	{
		// #64687#: The align=... attribute does behave strange in netscape
		// if there are controls in a paragraph, because the control and
		// all text behind the control does not recognize this attribute.
		ByteString sOut( '<' );
		sOut += OOO_STRING_SVTOOLS_HTML_division;
		rWrt.Strm() << sOut.GetBuffer();

		rHWrt.bTxtAttr = sal_False;
		rHWrt.bOutOpts = sal_True;
		OutHTML_SvxAdjust( rWrt, *pAdjItem );
		rWrt.Strm() << '>';
		pAdjItem = 0;
		rHWrt.bNoAlign = sal_False;
		rInfo.bOutDiv = sal_True;
		rHWrt.IncIndentLevel();
		rHWrt.bLFPossible = sal_True;
			rHWrt.OutNewLine();
	}

	// fuer BLOCKQUOTE, ADDRESS und DD wird noch ein Absatz-Token
	// ausgegeben, wenn,
	// - keine Styles geschrieben werden, und
	// - ein untere Abstand oder eine Absatz-Ausrichtung existiert
	ByteString aToken = rInfo.aToken;
	if( !rHWrt.bCfgOutStyles && rInfo.bParaPossible && !bPara &&
		(bHasParSpace || pAdjItem) )
	{
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), rInfo.aToken.GetBuffer() );
		aToken = OOO_STRING_SVTOOLS_HTML_parabreak;
		bPara = sal_True;
		rHWrt.bNoAlign = sal_False;
		bNoStyle = sal_False;
	}

	LanguageType eLang = rInfo.pItemSet
		? ((const SvxLanguageItem&)rInfo.pItemSet->Get(SwHTMLWriter::GetLangWhichIdFromScript(rHWrt.nCSS1Script))).GetLanguage()
	   	: rHWrt.eLang;

	if( rInfo.pItemSet )
	{
		static sal_uInt16 aWhichIds[3] = { RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CTL_LANGUAGE };

		for( sal_uInt16 i=0; i<3; i++ )
		{
			// export language if it differs from the default language only.
			const SfxPoolItem *pTmpItem;
			if( SFX_ITEM_SET == rInfo.pItemSet->GetItemState( aWhichIds[i],
						sal_True, &pTmpItem ) &&
				((const SvxLanguageItem *)pTmpItem)->GetLanguage() == eLang )
				rInfo.pItemSet->ClearItem( aWhichIds[i] );
		}
	}

	// and the text direction
	sal_uInt16 nDir = rHWrt.GetHTMLDirection(
			(pNodeItemSet ? static_cast < const SvxFrameDirectionItem& >(
									pNodeItemSet->Get( RES_FRAMEDIR ) )
						  : rFmt.GetFrmDir() ).GetValue() );

	// Ein <P> wird nur geschrieben, wenn
	// - wir in keiner OL/UL/DL sind, oder
	// - der Absatz einer OL/UL nicht numeriert ist, oder
	// - keine Styles exportiert werden und
	//      - ein unterer Abstand oder
	//      - eine Absatz-Ausrichtung existiert, ode
	// - Styles exportiert werden und,
	//		- die Textkoerper-Vorlage geaendert wurde, oder
	//   	- ein Benutzer-Format exportiert wird, oder
	//		- Absatz-Attribute existieren
	if( !bPara ||
		(!rInfo.bInNumBulList && !rHWrt.nDefListLvl) ||
		(rInfo.bInNumBulList && !bNumbered) ||
		(!rHWrt.bCfgOutStyles &&
		 (bHasParSpace || pAdjItem ||
		  (eLang != LANGUAGE_DONTKNOW && eLang != rHWrt.eLang))) ||
		nDir != rHWrt.nDirection ||
		rHWrt.bCfgOutStyles )
	{
		// jetzt werden Optionen ausgegeben
		rHWrt.bTxtAttr = sal_False;
		rHWrt.bOutOpts = sal_True;

		ByteString sOut( '<' );
		sOut += aToken;

		if( eLang != LANGUAGE_DONTKNOW && eLang != rHWrt.eLang )
		{
			rWrt.Strm() << sOut.GetBuffer();
			rHWrt.OutLanguage( eLang );
			sOut.Erase();
		}

		if( nDir != rHWrt.nDirection )
		{
			if( sOut.Len() )
			{
				rWrt.Strm() << sOut.GetBuffer();
				sOut.Erase();
			}
			rHWrt.OutDirection( nDir );
		}

		if( rHWrt.bCfgOutStyles &&
			(pFmtInfo->aClass.Len() || pFmtInfo->bScriptDependent) )
		{
			((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_class) += "=\"";
			rWrt.Strm() << sOut.GetBuffer();
			String aClass( pFmtInfo->aClass );
			if( pFmtInfo->bScriptDependent )
			{
				if( aClass.Len() )
				   aClass += '-';
				switch( rHWrt.nCSS1Script )
				{
				case CSS1_OUTMODE_WESTERN:
					aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("western") );
					break;
				case CSS1_OUTMODE_CJK:
					aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("cjk") );
					break;
				case CSS1_OUTMODE_CTL:
					aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("ctl") );
					break;
				}
			}
			HTMLOutFuncs::Out_String( rWrt.Strm(), aClass,
									  rHWrt.eDestEnc, &rHWrt.aNonConvertableCharacters );
			sOut = '\"';
		}
		rWrt.Strm() << sOut.GetBuffer();

		// ggf. Ausrichtung ausgeben.
		if( !rHWrt.bNoAlign && pAdjItem )
			OutHTML_SvxAdjust( rWrt, *pAdjItem );

		// und nun ggf. noch die STYLE-Option
		if( rHWrt.bCfgOutStyles && rInfo.pItemSet && !bNoStyle)
		{
			OutCSS1_ParaTagStyleOpt( rWrt, *rInfo.pItemSet );
		}

		rWrt.Strm() << '>';

		// Soll ein </P> geschrieben wenrden
		rInfo.bOutPara =
			bPara &&
			( rHWrt.bCfgOutStyles ||
				(!rHWrt.bCfgOutStyles && bHasParSpace) );

		// wenn kein End-Tag geschrieben werden soll, es loeschen
		if( bNoEndTag )
			rInfo.aToken.Erase();
	}

	// ??? Warum nicht ueber den Hint-Mechanismus ???
	if( rHWrt.IsHTMLMode(HTMLMODE_FIRSTLINE) )
	{
		const SvxLRSpaceItem& rLRSpaceTmp =
			pNodeItemSet ? ((const SvxLRSpaceItem &)pNodeItemSet->Get(RES_LR_SPACE))
						 : rFmt.GetLRSpace();
		if( rLRSpaceTmp.GetTxtFirstLineOfst() > 0 )
		{
			OutHTML_HoriSpacer( rWrt, rLRSpaceTmp.GetTxtFirstLineOfst() );
		}
	}

	if( nBulletGrfLvl != 255 )
	{
		ASSERT( aNumInfo.GetNumRule(), "Wo ist die Numerierung geblieben???" );
		ASSERT( nBulletGrfLvl < MAXLEVEL, "So viele Ebenen gibt's nicht" );
		const SwNumFmt& rNumFmt = aNumInfo.GetNumRule()->Get(nBulletGrfLvl);

		OutHTML_BulletImage( rWrt, OOO_STRING_SVTOOLS_HTML_image, 0,
							 rHWrt.aBulletGrfs[nBulletGrfLvl],
							 rNumFmt.GetGraphicSize(), rNumFmt.GetGraphicOrientation() );
	}

	rHWrt.GetNumInfo() = aNumInfo;

	// die Defaults zuruecksetzen
	rHWrt.nDfltLeftMargin = 0;
	rHWrt.nDfltRightMargin = 0;
	rHWrt.nDfltFirstLineIndent = 0;
	rHWrt.nDfltTopMargin = 0;
	rHWrt.nDfltBottomMargin = 0;
	rHWrt.nLeftMargin = 0;
	rHWrt.nFirstLineIndent = 0;
}

void OutHTML_SwFmtOff( Writer& rWrt, const SwHTMLTxtCollOutputInfo& rInfo )
{
	SwHTMLWriter & rHWrt = (SwHTMLWriter&)rWrt;

	// wenn es kein Token gibt haben wir auch nichts auszugeben
	if( !rInfo.aToken.Len() )
	{
		rHWrt.FillNextNumInfo();
		const SwHTMLNumRuleInfo& rNextInfo = *rHWrt.GetNextNumInfo();
		// Auch in PRE muss eine Bullet-Liste beendet werden
		if( rInfo.bInNumBulList )
		{

			const SwHTMLNumRuleInfo& rNRInfo = rHWrt.GetNumInfo();
			if( rNextInfo.GetNumRule() != rNRInfo.GetNumRule() ||
				rNextInfo.GetDepth() != rNRInfo.GetDepth() ||
				rNextInfo.IsNumbered() || rNextInfo.IsRestart() )
				rHWrt.ChangeParaToken( 0 );
			OutHTML_NumBulListEnd( rHWrt, rNextInfo );
		}
		else if( rNextInfo.GetNumRule() != 0 )
			rHWrt.ChangeParaToken( 0 );

		return;
	}

	if( rInfo.ShouldOutputToken() )
	{
		if( rHWrt.bLFPossible )
			rHWrt.OutNewLine( sal_True );

		// fuer BLOCKQUOTE, ADDRESS und DD wird ggf noch ein
		// Absatz-Token ausgegeben, wenn
		// - keine Styles geschrieben werden, und
		// - ein untere Abstand existiert
		if( rInfo.bParaPossible && rInfo.bOutPara )
			HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_parabreak, sal_False );

		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), rInfo.aToken.GetBuffer(),
									sal_False );
		rHWrt.bLFPossible = !rInfo.aToken.Equals( OOO_STRING_SVTOOLS_HTML_dt ) &&
							!rInfo.aToken.Equals( OOO_STRING_SVTOOLS_HTML_dd ) &&
							!rInfo.aToken.Equals( OOO_STRING_SVTOOLS_HTML_li );
	}
	if( rInfo.bOutDiv )
	{
		rHWrt.DecIndentLevel();
		if( rHWrt.bLFPossible )
			rHWrt.OutNewLine();
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_division, sal_False );
		rHWrt.bLFPossible = sal_True;
	}

	// ggf. eine Aufzaehlung- oder Numerierungsliste beenden
	if( rInfo.bInNumBulList )
	{
		rHWrt.FillNextNumInfo();
		OutHTML_NumBulListEnd( rHWrt, *rHWrt.GetNextNumInfo() );
	}
}


class HTMLSttEndPos
{
	xub_StrLen nStart;
	xub_StrLen nEnd;
	SfxPoolItem* pItem;

public:

	HTMLSttEndPos( const SfxPoolItem& rItem, xub_StrLen nStt, xub_StrLen nE );
	~HTMLSttEndPos();

	const SfxPoolItem *GetItem() const { return pItem; }

	void SetStart( xub_StrLen nStt ) { nStart = nStt; }
	xub_StrLen GetStart() const { return nStart; }

	xub_StrLen GetEnd() const { return nEnd; }
	void SetEnd( xub_StrLen nE ) { nEnd = nE; }
};

HTMLSttEndPos::HTMLSttEndPos( const SfxPoolItem& rItem, xub_StrLen nStt,
														xub_StrLen nE ) :
	nStart( nStt ),
	nEnd( nE ),
	pItem( rItem.Clone() )
{}

HTMLSttEndPos::~HTMLSttEndPos()
{
	delete pItem;
}

typedef HTMLSttEndPos *HTMLSttEndPosPtr;
SV_DECL_PTRARR( _HTMLEndLst, HTMLSttEndPosPtr, 5, 5 )

enum HTMLOnOffState { HTML_NOT_SUPPORTED, 	// nicht unterst. Attribut
					  HTML_REAL_VALUE, 		// Attribut mit Wert
					  HTML_ON_VALUE, 		// Attribut entspricht On-Tag
					  HTML_OFF_VALUE,		// Attribut entspricht Off-Tag
					  HTML_CHRFMT_VALUE,	// Attribut fuer Zeichenvorlage
					  HTML_COLOR_VALUE,		// Attribut fuer Vordergrundfarbe
					  HTML_STYLE_VALUE,		// Attribut muss als Style exp.
					  HTML_DROPCAP_VALUE, 	// DropCap-Attributs
					  HTML_AUTOFMT_VALUE };	// Attribute for automatic character styles


class HTMLEndPosLst
{
	_HTMLEndLst aStartLst;	// nach Anfangs-Psoitionen sortierte Liste
	_HTMLEndLst aEndLst;	// nach End-Psotionen sortierte Liste
	SvXub_StrLens aScriptChgLst;	// positions where script changes
									// 0 is not contained in this list,
									// but the text length
    // the script that is valif up to the position
    // contained in aScriptChgList at the same index
    ::std::vector<sal_uInt16> aScriptLst;

	SwDoc *pDoc;			// das aktuelle Dokument
	SwDoc* pTemplate;		// die HTML-Vorlage (oder 0)
	const Color* pDfltColor;// die Default-Vordergrund-Farbe
	SvStringsSortDtor& rScriptTxtStyles;	//

	sal_uLong nHTMLMode;
	sal_Bool bOutStyles : 1;	// werden Styles exportiert


	// die Position eines Items in der Start-/Ende-Liste suchen
	sal_uInt16 _FindStartPos( const HTMLSttEndPos *pPos ) const;
	sal_uInt16 _FindEndPos( const HTMLSttEndPos *pPos ) const;

	// Eine SttEndPos in die Start- und Ende-Listen eintragen bzw. aus
	// ihnen loeschen, wobei die Ende-Position bekannt ist
	void _InsertItem( HTMLSttEndPos *pPos, sal_uInt16 nEndPos );
	void _RemoveItem( sal_uInt16 nEndPos );

	// die "Art" es Attributs ermitteln
	HTMLOnOffState GetHTMLItemState( const SfxPoolItem& rItem );

	// Existiert ein bestimmtes On-Tag-Item
	sal_Bool ExistsOnTagItem( sal_uInt16 nWhich, xub_StrLen nPos );

	// Existiert ein Item zum ausschalten eines Attributs, das genauso
	// exportiert wird wie das uebergebene Item im gleichen Bereich?
	sal_Bool ExistsOffTagItem( sal_uInt16 nWhich, xub_StrLen nStartPos,
										  xub_StrLen nEndPos );


	// das Ende eines gesplitteten Items anpassen
	void FixSplittedItem( HTMLSttEndPos *pPos, sal_uInt16 nStartPos,
						  xub_StrLen nNewEnd );

	// Ein Attribut in die Listen eintragen und ggf. aufteilen
	void InsertItem( const SfxPoolItem& rItem, xub_StrLen nStart,
											   xub_StrLen nEnd );

	// Ein bereits vorhandenes Attribut aufteilen
	void SplitItem( const SfxPoolItem& rItem, xub_StrLen nStart,
											  xub_StrLen nEnd );

	// Insert without taking care of script
	void InsertNoScript( const SfxPoolItem& rItem, xub_StrLen nStart,
					 	 xub_StrLen nEnd, SwHTMLFmtInfos& rFmtInfos,
						 sal_Bool bParaAttrs=sal_False );

	const SwHTMLFmtInfo *GetFmtInfo( const SwFmt& rFmt,
									 SwHTMLFmtInfos& rFmtInfos );

public:

	HTMLEndPosLst( SwDoc *pDoc, SwDoc* pTemplate, const Color* pDfltColor,
				   sal_Bool bOutStyles, sal_uLong nHTMLMode,
				   const String& rText, SvStringsSortDtor& rStyles );
	~HTMLEndPosLst();

	// Ein Attribut einfuegen
	void Insert( const SfxPoolItem& rItem, xub_StrLen nStart,  xub_StrLen nEnd,
				 SwHTMLFmtInfos& rFmtInfos, sal_Bool bParaAttrs=sal_False );
	void Insert( const SfxItemSet& rItemSet, xub_StrLen nStart, xub_StrLen nEnd,
				 SwHTMLFmtInfos& rFmtInfos, sal_Bool bDeep,
				 sal_Bool bParaAttrs=sal_False );
	void Insert( const SwDrawFrmFmt& rFmt, xub_StrLen nPos,
				 SwHTMLFmtInfos& rFmtInfos );

	sal_uInt16 GetScriptAtPos( xub_StrLen nPos,
							   sal_uInt16 nWeak=CSS1_OUTMODE_ANY_SCRIPT );

	void OutStartAttrs( SwHTMLWriter& rHWrt, xub_StrLen nPos,
						HTMLOutContext *pContext = 0 );
	void OutEndAttrs( SwHTMLWriter& rHWrt, xub_StrLen nPos,
					  HTMLOutContext *pContext = 0 );

	sal_uInt16 Count() const { return aEndLst.Count(); }

	sal_Bool IsHTMLMode( sal_uLong nMode ) const { return (nHTMLMode & nMode) != 0; }
};


sal_uInt16 HTMLEndPosLst::_FindStartPos( const HTMLSttEndPos *pPos ) const
{
	sal_uInt16 i;
	for( i = 0; i < aStartLst.Count() && aStartLst[i] != pPos;  i++ )
		;

	ASSERT( i != aStartLst.Count(), "Item nicht in Start-Liste gefunden!" );

	return i==aStartLst.Count() ? USHRT_MAX : i;
}

sal_uInt16 HTMLEndPosLst::_FindEndPos( const HTMLSttEndPos *pPos ) const
{
	sal_uInt16 i;

	for( i = 0; i < aEndLst.Count() && aEndLst[i] != pPos;  i++ )
		;

	ASSERT( i != aEndLst.Count(), "Item nicht in Ende-Liste gefunden" );

	return i==aEndLst.Count() ? USHRT_MAX : i;
}


void HTMLEndPosLst::_InsertItem( HTMLSttEndPos *pPos, sal_uInt16 nEndPos )
{
	// In der Start-Liste das Attribut hinter allen vorher und an
	// der gleichen Position gestarteten Attributen einfuegen
	xub_StrLen nStart = pPos->GetStart();
	sal_uInt16 i;

	for( i = 0; i < aStartLst.Count() &&
					 aStartLst[i]->GetStart() <= nStart; i++ )
		;
	aStartLst.Insert( pPos, i );

	// die Position in der Ende-Liste wurde uebergeben
	aEndLst.Insert( pPos, nEndPos );
}

void HTMLEndPosLst::_RemoveItem( sal_uInt16 nEndPos )
{
	HTMLSttEndPos *pPos = aEndLst[nEndPos];

	// jetzt Suchen wir es in der Start-Liste
	sal_uInt16 nStartPos = _FindStartPos( pPos );
	if( nStartPos != USHRT_MAX )
		aStartLst.Remove( nStartPos, 1 );

	aEndLst.Remove( nEndPos, 1 );

	delete pPos;
}

HTMLOnOffState HTMLEndPosLst::GetHTMLItemState( const SfxPoolItem& rItem )
{
	HTMLOnOffState eState = HTML_NOT_SUPPORTED;
	switch( rItem.Which() )
	{
	case RES_CHRATR_POSTURE:
	case RES_CHRATR_CJK_POSTURE:
	case RES_CHRATR_CTL_POSTURE:
		switch( ((const SvxPostureItem&)rItem).GetPosture() )
		{
		case ITALIC_NORMAL:
			eState = HTML_ON_VALUE;
			break;
		case ITALIC_NONE:
			eState = HTML_OFF_VALUE;
			break;
		default:
			if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
				eState = HTML_STYLE_VALUE;
			break;
		}
		break;

	case RES_CHRATR_CROSSEDOUT:
		switch( ((const SvxCrossedOutItem&)rItem).GetStrikeout() )
		{
		case STRIKEOUT_SINGLE:
		case STRIKEOUT_DOUBLE:
			eState = HTML_ON_VALUE;
			break;
		case STRIKEOUT_NONE:
			eState = HTML_OFF_VALUE;
			break;
		default:
			;
		}
		break;

	case RES_CHRATR_ESCAPEMENT:
		switch( (const SvxEscapement)
						((const SvxEscapementItem&)rItem).GetEnumValue() )
		{
		case SVX_ESCAPEMENT_SUPERSCRIPT:
		case SVX_ESCAPEMENT_SUBSCRIPT:
			eState = HTML_ON_VALUE;
			break;
		case SVX_ESCAPEMENT_OFF:
			eState = HTML_OFF_VALUE;
			break;
		default:
			;
		}
		break;

	case RES_CHRATR_UNDERLINE:
		switch( ((const SvxUnderlineItem&)rItem).GetLineStyle() )
		{
		case UNDERLINE_SINGLE:
			eState = HTML_ON_VALUE;
			break;
		case UNDERLINE_NONE:
			eState = HTML_OFF_VALUE;
			break;
		default:
			if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
				eState = HTML_STYLE_VALUE;
			break;
		}
		break;

	case RES_CHRATR_OVERLINE:
		if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
			eState = HTML_STYLE_VALUE;
		break;

	case RES_CHRATR_WEIGHT:
	case RES_CHRATR_CJK_WEIGHT:
	case RES_CHRATR_CTL_WEIGHT:
		switch( ((const SvxWeightItem&)rItem).GetWeight() )
		{
		case WEIGHT_BOLD:
			eState = HTML_ON_VALUE;
			break;
		case WEIGHT_NORMAL:
			eState = HTML_OFF_VALUE;
			break;
		default:
			if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
				eState = HTML_STYLE_VALUE;
			break;
		}
		break;

	case RES_CHRATR_BLINK:
		if( IsHTMLMode(HTMLMODE_BLINK) )
			eState = ((const SvxBlinkItem&)rItem).GetValue() ? HTML_ON_VALUE
															 : HTML_OFF_VALUE;
		break;

	case RES_CHRATR_COLOR:
		eState = HTML_COLOR_VALUE;
		break;

	case RES_CHRATR_FONT:
	case RES_CHRATR_FONTSIZE:
	case RES_CHRATR_LANGUAGE:
	case RES_CHRATR_CJK_FONT:
	case RES_CHRATR_CJK_FONTSIZE:
	case RES_CHRATR_CJK_LANGUAGE:
	case RES_CHRATR_CTL_FONT:
	case RES_CHRATR_CTL_FONTSIZE:
	case RES_CHRATR_CTL_LANGUAGE:
	case RES_TXTATR_INETFMT:
		eState = HTML_REAL_VALUE;
		break;

	case RES_TXTATR_CHARFMT:
		eState = HTML_CHRFMT_VALUE;
		break;

	case RES_TXTATR_AUTOFMT:
		eState = HTML_AUTOFMT_VALUE;
		break;

	case RES_CHRATR_CASEMAP:
		if( IsHTMLMode(HTMLMODE_SMALL_CAPS) )
			eState = HTML_STYLE_VALUE;

	case RES_CHRATR_KERNING:
		if( IsHTMLMode(HTMLMODE_FULL_STYLES) )
			eState = HTML_STYLE_VALUE;
		break;

	case RES_CHRATR_BACKGROUND:
		if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
			eState = HTML_STYLE_VALUE;
		break;

	case RES_PARATR_DROP:
		eState = HTML_DROPCAP_VALUE;
		break;

//	default:
//		eState = HTML_NOT_SUPPORTED;
//		break;
	}

	return eState;
}

sal_Bool HTMLEndPosLst::ExistsOnTagItem( sal_uInt16 nWhich, xub_StrLen nPos )
{
	for( sal_uInt16 i=0; i<aStartLst.Count(); i++ )
	{
		HTMLSttEndPos *pTest = aStartLst[i];

		if( pTest->GetStart() > nPos )
		{
			// dieses uns alle folgenden Attribute beginnen spaeter
			break;
		}
		else if( pTest->GetEnd() > nPos )
		{
			// das Attribut beginnt vor oder an der aktuellen Position
			// und endet hinter ihr
			const SfxPoolItem *pItem = pTest->GetItem();
			if( pItem->Which() == nWhich &&
				HTML_ON_VALUE == GetHTMLItemState(*pItem) )
			{
				// ein On-Tag-Attibut wurde gefunden
				return sal_True;
			}
		}
	}

	return sal_False;
}

sal_Bool HTMLEndPosLst::ExistsOffTagItem( sal_uInt16 nWhich, xub_StrLen nStartPos,
									  xub_StrLen nEndPos )
{
	if( nWhich != RES_CHRATR_CROSSEDOUT &&
		nWhich != RES_CHRATR_UNDERLINE &&
		nWhich != RES_CHRATR_BLINK )
	{
		return sal_False;
	}

	for( sal_uInt16 i=0; i<aStartLst.Count(); i++ )
	{
		HTMLSttEndPos *pTest = aStartLst[i];

		if( pTest->GetStart() > nStartPos )
		{
			// dieses uns alle folgenden Attribute beginnen spaeter
			break;
		}
		else if( pTest->GetStart()==nStartPos &&
				 pTest->GetEnd()==nEndPos )
		{
			// das Attribut beginnt vor oder an der aktuellen Position
			// und endet hinter ihr
			const SfxPoolItem *pItem = pTest->GetItem();
			sal_uInt16 nTstWhich = pItem->Which() ;
			if( (nTstWhich == RES_CHRATR_CROSSEDOUT ||
				 nTstWhich == RES_CHRATR_UNDERLINE ||
				 nTstWhich == RES_CHRATR_BLINK) &&
				HTML_OFF_VALUE == GetHTMLItemState(*pItem) )
			{
				// Ein Off-Tag-Attibut wurde gefunden, das genauso
				// exportiert wird, wie das aktuelle Item
				return sal_True;
			}
		}
	}

	return sal_False;
}

void HTMLEndPosLst::FixSplittedItem( HTMLSttEndPos *pPos, xub_StrLen nNewEnd,
									 sal_uInt16 nStartPos )
{
	// die End-Position entsprechend fixen
	pPos->SetEnd( nNewEnd );

	// das Item aus der End-Liste entfernen
	sal_uInt16 nEndPos = _FindEndPos( pPos );
	if( nEndPos != USHRT_MAX )
		aEndLst.Remove( nEndPos, 1 );

	// es wird von nun an als letztes an der entsprechenden Position
	// beendet
	for( nEndPos=0; nEndPos < aEndLst.Count() &&
					aEndLst[nEndPos]->GetEnd() <= nNewEnd; nEndPos++ )
		;
	aEndLst.Insert( pPos, nEndPos );

	// jetzt noch die spaeter gestarteten Attribute anpassen
	for( sal_uInt16 i=nStartPos+1; i<aStartLst.Count(); i++ )
	{
		HTMLSttEndPos *pTest = aStartLst[i];
		xub_StrLen nTestEnd = pTest->GetEnd();
		if( pTest->GetStart() >= nNewEnd )
		{
			// das Test-Attribut und alle folgenden beginnen, nachdem das
			// gesplittete Attribut endet
			break;
		}
		else if( nTestEnd > nNewEnd )
		{
			// das Test-Attribut beginnt, bevor das gesplittete Attribut
			// endet und endet danach, muss also auch gesplittet werden

			// das neue Ende setzen
			pTest->SetEnd( nNewEnd );

			// das Attribut aus der End-Liste entfernen
			sal_uInt16 nEPos = _FindEndPos( pTest );
			if( nEPos != USHRT_MAX )
				aEndLst.Remove( nEPos, 1 );

			// es endet jetzt als erstes Attribut an der entsprechenden
			// Position. Diese Position in der Ende-Liste kennen wir schon.
			aEndLst.Insert(pTest, nEndPos );

			// den "Rest" des Attributs neu einfuegen
			InsertItem( *pTest->GetItem(), nNewEnd, nTestEnd );
		}
	}
}


void HTMLEndPosLst::InsertItem( const SfxPoolItem& rItem, xub_StrLen nStart,
														  xub_StrLen nEnd )
{
	sal_uInt16 i;
	for( i = 0; i < aEndLst.Count(); i++ )
	{
		HTMLSttEndPos *pTest = aEndLst[i];
		xub_StrLen nTestEnd = pTest->GetEnd();
		if( nTestEnd <= nStart )
		{
			// das Test-Attribut endet, bevor das neue beginnt
			continue;
		}
		else if( nTestEnd < nEnd )
		{
			// das Test-Attribut endet, bevor das neue endet. Das
			// neue Attribut muss deshalb aufgesplittet werden
			_InsertItem( new HTMLSttEndPos( rItem, nStart, nTestEnd ), i );
			nStart = nTestEnd;
		}
		else
		{
			// das Test-Attribut (und alle folgenden) endet, bevor das neue
			// endet
			break;
		}
	}

	// ein Attribut muss noch eingefuegt werden
	_InsertItem( new HTMLSttEndPos( rItem, nStart, nEnd ), i );
}



void HTMLEndPosLst::SplitItem( const SfxPoolItem& rItem, xub_StrLen nStart,
													  	 xub_StrLen nEnd )
{
	sal_uInt16 nWhich = rItem.Which();

	// erstmal muessen wir die alten Items anhand der Startliste suchen
	// und die neuen Item-Bereiche festlegen

	for( sal_uInt16 i=0; i<aStartLst.Count(); i++ )
	{
		HTMLSttEndPos *pTest = aStartLst[i];
		xub_StrLen nTestStart = pTest->GetStart();
		xub_StrLen nTestEnd = pTest->GetEnd();

		if( nTestStart >= nEnd )
		{
			// dieses und alle nachfolgenden Attribute beginnen spaeter
			break;
		}
		else if( nTestEnd > nStart )
		{
			// das Test Attribut endet im zu loeschenenden Bereich
			const SfxPoolItem *pItem = pTest->GetItem();

			// nur entsprechende On-Tag Attribute muessen beruecksichtigt
			// werden
			if( pItem->Which() == nWhich &&
				HTML_ON_VALUE == GetHTMLItemState( *pItem ) )
			{
				sal_Bool bDelete = sal_True;

				if( nTestStart < nStart )
				{
					// der Start des neuen Attribut entspricht
					// dem neuen Ende des Attribts
					FixSplittedItem( pTest, nStart, i );
					bDelete = sal_False;
				}
				else
				{
					// das Test-Item beginnt erst hinter dem neuen
					// Ende des Attribts und kann deshalb komplett
					// geloescht werden
					aStartLst.Remove( i, 1 );
					i--;

					sal_uInt16 nEndPos = _FindEndPos( pTest );
					if( nEndPos != USHRT_MAX )
						aEndLst.Remove( nEndPos, 1 );
				}

				// ggf den zweiten Teil des gesplitteten Attribts einfuegen
				if( nTestEnd > nEnd )
				{
					InsertItem( *pTest->GetItem(), nEnd, nTestEnd );
				}

				if( bDelete )
					delete pTest;
			}
		}
	}
}

const SwHTMLFmtInfo *HTMLEndPosLst::GetFmtInfo( const SwFmt& rFmt,
												SwHTMLFmtInfos& rFmtInfos )
{
	const SwHTMLFmtInfo *pFmtInfo;
	SwHTMLFmtInfo aFmtInfo( &rFmt );
	sal_uInt16 nPos;
	if( rFmtInfos.Seek_Entry( &aFmtInfo, &nPos ) )
	{
		pFmtInfo = rFmtInfos[nPos];
	}
	else
	{
		pFmtInfo = new SwHTMLFmtInfo( &rFmt, pDoc, pTemplate,
									  bOutStyles );
		rFmtInfos.C40_PTR_INSERT( SwHTMLFmtInfo, pFmtInfo );
		String aName( rFmt.GetName() );
		if( rScriptTxtStyles.Seek_Entry( &aName ) )
			((SwHTMLFmtInfo *)pFmtInfo)->bScriptDependent = sal_True;
	}

	return pFmtInfo;
}

HTMLEndPosLst::HTMLEndPosLst( SwDoc *pD, SwDoc* pTempl,
							  const Color* pDfltCol, sal_Bool bStyles,
							  sal_uLong nMode, const String& rText,
							  SvStringsSortDtor& rStyles ):
	pDoc( pD ),
	pTemplate( pTempl ),
	pDfltColor( pDfltCol ),
	rScriptTxtStyles( rStyles ),
	nHTMLMode( nMode ),
	bOutStyles( bStyles )
{
	xub_StrLen nEndPos = rText.Len();
	xub_StrLen nPos = 0;
	while( nPos < nEndPos )
	{
		sal_uInt16 nScript = pBreakIt->GetBreakIter()->getScriptType( rText, nPos );
		nPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript( rText, nPos, nScript );
		aScriptChgLst.push_back( nPos );
        aScriptLst.push_back( nScript );
    }
}

HTMLEndPosLst::~HTMLEndPosLst()
{
	ASSERT( !aStartLst.Count(), "Start-Liste im Destruktor nicht leer" );
	ASSERT( !aEndLst.Count(), "End-Liste im Destruktor nicht leer" );
}



void HTMLEndPosLst::InsertNoScript( const SfxPoolItem& rItem,
							xub_StrLen nStart, xub_StrLen nEnd,
							SwHTMLFmtInfos& rFmtInfos, sal_Bool bParaAttrs )
{
	// kein Bereich ?? dann nicht aufnehmen, wird nie wirksam !!
	if( nStart != nEnd )
	{
		sal_Bool bSet = sal_False, bSplit = sal_False;
		switch( GetHTMLItemState(rItem) )
		{
		case HTML_ON_VALUE:
			// das Attribut wird ausgegeben, wenn es nicht sowieso
			// schon an ist
			if( !ExistsOnTagItem( rItem.Which(), nStart ) )
				bSet = sal_True;
			break;

		case HTML_OFF_VALUE:
			// wenn das entsprechne Attribut an ist, wird es gesplittet,
			// Zusaetlich wird es aber als Style ausgegeben, wenn es nicht
			// am ganzen Absatz gesetzt ist, weil es dann ja schon mit dem
			// ABsatz-Tag ausgegeben wurde.
			if( ExistsOnTagItem( rItem.Which(), nStart ) )
				bSplit = sal_True;
			bSet = bOutStyles && !bParaAttrs &&
				   !ExistsOffTagItem( rItem.Which(), nStart, nEnd );
			break;

		case HTML_REAL_VALUE:
			// das Attribut kann immer ausgegeben werden
			bSet = sal_True;
			break;

		case HTML_STYLE_VALUE:
			// Das Attribut kann nur als CSS1 ausgegeben werden. Wenn
			// es am Absatz gesetzt ist, wurde es schon mit dem
			// Absatz-Tag ausgegeben. Einzige Ausnahme ist das
			// Zeichen-Hintergrund-Attribut. Es muss immer wie ein
			// Hint behandelt werden.
			bSet = bOutStyles &&
				   (!bParaAttrs
				  || rItem.Which()==RES_CHRATR_BACKGROUND
				  || rItem.Which()==RES_CHRATR_OVERLINE);
			break;

		case HTML_CHRFMT_VALUE:
			{
				ASSERT( RES_TXTATR_CHARFMT == rItem.Which(),
						"Doch keine Zeichen-Vorlage" );
				const SwFmtCharFmt& rChrFmt = (const SwFmtCharFmt&)rItem;
				const SwCharFmt* pFmt = rChrFmt.GetCharFmt();

				const SwHTMLFmtInfo *pFmtInfo = GetFmtInfo( *pFmt, rFmtInfos );
				if( pFmtInfo->aToken.Len() )
				{
					// das Zeichenvorlagen-Tag muss vor den harten
					// Attributen ausgegeben werden
					InsertItem( rItem, nStart, nEnd );
				}
				if( pFmtInfo->pItemSet )
				{
					Insert( *pFmtInfo->pItemSet, nStart, nEnd,
							rFmtInfos, sal_True, bParaAttrs );
				}
			}
			break;

		case HTML_AUTOFMT_VALUE:
			{
				const SwFmtAutoFmt& rAutoFmt = (const SwFmtAutoFmt&)rItem;
                const boost::shared_ptr<SfxItemSet> pSet = rAutoFmt.GetStyleHandle();
                if( pSet.get() )
					Insert( *pSet.get(), nStart, nEnd, rFmtInfos, sal_True, bParaAttrs );
			}
			break;

		case HTML_COLOR_VALUE:
			// Eine Vordergrund-Farbe als Absatz-Attribut wird nur
			// exportiert, wenn sie nicht der Default-Farbe entspricht.
			{
				ASSERT( RES_CHRATR_COLOR == rItem.Which(),
						"Doch keine Vordergrund-Farbe" );
				Color aColor( ((const SvxColorItem&)rItem).GetValue() );
				if( COL_AUTO == aColor.GetColor() )
					aColor.SetColor( COL_BLACK );
				bSet = !bParaAttrs || !pDfltColor ||
					   !pDfltColor->IsRGBEqual( aColor );
			}
			break;

		case HTML_DROPCAP_VALUE:
			{
				ASSERT( RES_PARATR_DROP == rItem.Which(),
						"Doch kein Drop-Cap" );
				const SwFmtDrop& rDrop = (const SwFmtDrop&)rItem;
				nEnd = nStart + rDrop.GetChars();
				if( !bOutStyles )
				{
					// Zumindest die Attribute der Zeichenvorlage uebernehmen
					const SwCharFmt *pCharFmt = rDrop.GetCharFmt();
					if( pCharFmt )
					{
						Insert( pCharFmt->GetAttrSet(), nStart, nEnd,
								rFmtInfos, sal_True, bParaAttrs );
					}
				}
				else
				{
					bSet = sal_True;
				}
			}
			break;
		default:
			;
		}

		if( bSet )
			InsertItem( rItem, nStart, nEnd );
		if( bSplit )
			SplitItem( rItem, nStart, nEnd );
	}
}

void HTMLEndPosLst::Insert( const SfxPoolItem& rItem,
							xub_StrLen nStart, xub_StrLen nEnd,
							SwHTMLFmtInfos& rFmtInfos, sal_Bool bParaAttrs )
{
	sal_Bool bDependsOnScript = sal_False, bDependsOnAnyScript = sal_False;
    sal_uInt16 nScript = i18n::ScriptType::LATIN;
	switch( rItem.Which() )
	{
	case RES_CHRATR_FONT:
	case RES_CHRATR_FONTSIZE:
	case RES_CHRATR_LANGUAGE:
	case RES_CHRATR_POSTURE:
	case RES_CHRATR_WEIGHT:
		bDependsOnScript = sal_True;
        nScript = i18n::ScriptType::LATIN;
		break;

	case RES_CHRATR_CJK_FONT:
	case RES_CHRATR_CJK_FONTSIZE:
	case RES_CHRATR_CJK_LANGUAGE:
	case RES_CHRATR_CJK_POSTURE:
	case RES_CHRATR_CJK_WEIGHT:
		bDependsOnScript = sal_True;
        nScript = i18n::ScriptType::ASIAN;
		break;

	case RES_CHRATR_CTL_FONT:
	case RES_CHRATR_CTL_FONTSIZE:
	case RES_CHRATR_CTL_LANGUAGE:
	case RES_CHRATR_CTL_POSTURE:
	case RES_CHRATR_CTL_WEIGHT:
		bDependsOnScript = sal_True;
        nScript = i18n::ScriptType::COMPLEX;
		break;
	case RES_TXTATR_CHARFMT:
		{
			const SwFmtCharFmt& rChrFmt = (const SwFmtCharFmt&)rItem;
			const SwCharFmt* pFmt = rChrFmt.GetCharFmt();
			const SwHTMLFmtInfo *pFmtInfo = GetFmtInfo( *pFmt, rFmtInfos );
			if( pFmtInfo->bScriptDependent )
			{
				bDependsOnScript = sal_True;
				bDependsOnAnyScript = sal_True;
			}
		}
		break;
	case RES_TXTATR_INETFMT:
		{
			if( GetFmtInfo( *pDoc->GetCharFmtFromPool(
					 RES_POOLCHR_INET_NORMAL), rFmtInfos )->bScriptDependent ||
				GetFmtInfo( *pDoc->GetCharFmtFromPool(
					 RES_POOLCHR_INET_VISIT), rFmtInfos )->bScriptDependent )
			{
				bDependsOnScript = sal_True;
				bDependsOnAnyScript = sal_True;
			}
		}
		break;
	}

	if( bDependsOnScript )
	{
		xub_StrLen nPos = nStart;
		for( size_t i=0; i < aScriptChgLst.size(); i++ )
		{
			xub_StrLen nChgPos = aScriptChgLst[i];
			if( nPos >= nChgPos )
			{
				// the hint starts behind or at the next script change,
				// so we may continue with this position.
				continue;
			}
			if( nEnd <= nChgPos )
			{
				// the (rest of) the hint ends before or at the next script
				// change, so we can insert it, but only if it belongs
				// to the current script.
				if( bDependsOnAnyScript || nScript == aScriptLst[i] )
					InsertNoScript( rItem, nPos, nEnd, rFmtInfos,
									bParaAttrs );
				break;
			}

			// the hint starts before the next script change and ends behind
			// it, so we can insert a hint upto the next script change and
			// continue with the rest of the hint.
			if( bDependsOnAnyScript || nScript == aScriptLst[i] )
				InsertNoScript( rItem, nPos, nChgPos, rFmtInfos, bParaAttrs );
			nPos = nChgPos;
		}
	}
	else
	{
		InsertNoScript( rItem, nStart, nEnd, rFmtInfos, bParaAttrs );
	}
}

void HTMLEndPosLst::Insert( const SfxItemSet& rItemSet,
							xub_StrLen nStart, xub_StrLen nEnd,
							SwHTMLFmtInfos& rFmtInfos,
							sal_Bool bDeep, sal_Bool bParaAttrs )
{
	SfxWhichIter aIter( rItemSet );

	sal_uInt16 nWhich = aIter.FirstWhich();
	while( nWhich )
	{
		const SfxPoolItem *pItem;
		if( SFX_ITEM_SET == rItemSet.GetItemState( nWhich, bDeep, &pItem ) )
		{
			Insert( *pItem, nStart, nEnd, rFmtInfos, bParaAttrs );
		}

		nWhich = aIter.NextWhich();
	}
}

void HTMLEndPosLst::Insert( const SwDrawFrmFmt& rFmt, xub_StrLen nPos,
							SwHTMLFmtInfos& rFmtInfos )
{
	// der Type-Cast ist nur noetig, um nicht seinetwegen
	// svdrwobt.hxx zu includem
	const SdrObject* pTextObj =
		(const SdrObject *)SwHTMLWriter::GetMarqueeTextObj( rFmt );

	if( pTextObj )
	{
		// die Edit-Engine-Attribute des Objekts als SW-Attribute holen
		// und als Hints einsortieren. Wegen der Menge der Hints werden
		// Styles hierbei nicht beruecksichtigt!
		const SfxItemSet& rFmtItemSet = rFmt.GetAttrSet();
		SfxItemSet aItemSet( *rFmtItemSet.GetPool(), RES_CHRATR_BEGIN,
													 RES_CHRATR_END );
		SwHTMLWriter::GetEEAttrsFromDrwObj( aItemSet, pTextObj, sal_True );
		sal_Bool bOutStylesOld = bOutStyles;
		bOutStyles = sal_False;
		Insert( aItemSet, nPos, nPos+1, rFmtInfos, sal_False, sal_False );
		bOutStyles = bOutStylesOld;
	}
}

sal_uInt16 HTMLEndPosLst::GetScriptAtPos( xub_StrLen nPos ,
							   			  sal_uInt16 nWeak )
{
	sal_uInt16 nRet = CSS1_OUTMODE_ANY_SCRIPT;

	size_t nScriptChgs = aScriptChgLst.size();
	size_t i=0;
	while( i < nScriptChgs && nPos >= aScriptChgLst[i] )
		i++;
	ASSERT( i < nScriptChgs, "script list is to short" );
	if( i < nScriptChgs )
	{
        if( i18n::ScriptType::WEAK == aScriptLst[i] )
			nRet = nWeak;
		else
			nRet = SwHTMLWriter::GetCSS1ScriptForScriptType( aScriptLst[i] );
	}

	return nRet;
}

void HTMLEndPosLst::OutStartAttrs( SwHTMLWriter& rHWrt, xub_StrLen nPos,
	   							   HTMLOutContext *pContext	)
{
	rHWrt.bTagOn = sal_True;

	// die Attribute in der Start-Liste sind aufsteigend sortiert
	for( sal_uInt16 i=0; i< aStartLst.Count(); i++ )
	{
		HTMLSttEndPos *pPos = aStartLst[i];
		xub_StrLen nStart = pPos->GetStart();
		if( nStart > nPos )
		{
			// dieses und alle folgenden Attribute werden erst noch geoeffnet
			break;
		}
		else if( nStart == nPos )
		{
			// das Attribut ausgeben
			sal_uInt16 nCSS1Script = rHWrt.nCSS1Script;
			sal_uInt16 nWhich = pPos->GetItem()->Which();
			if( RES_TXTATR_CHARFMT == nWhich ||
				RES_TXTATR_INETFMT == nWhich ||
			 	RES_PARATR_DROP == nWhich )
			{
				rHWrt.nCSS1Script = GetScriptAtPos( nPos, nCSS1Script );
			}
			if( pContext )
			{
				HTMLOutFuncs::FlushToAscii( rHWrt.Strm(), *pContext );
				pContext = 0; // one time ony
			}
			Out( aHTMLAttrFnTab, *pPos->GetItem(), rHWrt );
			rHWrt.nCSS1Script = nCSS1Script;
		}
	}
}

void HTMLEndPosLst::OutEndAttrs( SwHTMLWriter& rHWrt, xub_StrLen nPos,
	   						 	 HTMLOutContext *pContext )
{
	rHWrt.bTagOn = sal_False;

	// die Attribute in der End-Liste sind aufsteigend sortiert
	sal_uInt16 i=0;
	while( i < aEndLst.Count() )
	{
		HTMLSttEndPos *pPos = aEndLst[i];
		xub_StrLen nEnd = pPos->GetEnd();

		if( STRING_MAXLEN==nPos || nEnd == nPos )
		{
			if( pContext )
			{
				HTMLOutFuncs::FlushToAscii( rHWrt.Strm(), *pContext );
				pContext = 0; // one time ony
			}
			Out( aHTMLAttrFnTab, *pPos->GetItem(), rHWrt );
			_RemoveItem( i );
		}
		else if( nEnd > nPos )
		{
			// dieses und alle folgenden Attribute werden erst spaeter beendet
			break;
		}
		else
		{
			// Das Attribut wird vor der aktuellen Position beendet. Das
			// darf nicht sein, aber wie koennen trotzdem damit umgehen
			ASSERT( nEnd >= nPos,
					"Das Attribut sollte schon laengst beendet sein" );
			i++;
		}
	}
}


/* Ausgabe der Nodes */
Writer& OutHTML_SwTxtNode( Writer& rWrt, const SwCntntNode& rNode )
{
	SwTxtNode * pNd = &((SwTxtNode&)rNode);
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;

	const String& rStr = pNd->GetTxt();
	xub_StrLen nEnde = rStr.Len();

	// Besonderheit: leere Node und HR-Vorlage (horizontaler Strich)
	// 				nur ein <HR> ausgeben
	sal_uInt16 nPoolId = pNd->GetAnyFmtColl().GetPoolFmtId();

	if( !nEnde && (RES_POOLCOLL_HTML_HR==nPoolId ||
				   pNd->GetAnyFmtColl().GetName().EqualsAscii( OOO_STRING_SVTOOLS_HTML_horzrule) ) )
	{
		// dann die absatz-gebundenen Grafiken/OLE-Objekte im Absatz
		// MIB 8.7.97: Ein <PRE> spannen wir um die Linie auf. Dann stimmen
		// zwar die Abstaende nicht, aber sonst bekommen wir einen leeren
		// Absatz hinter dem <HR> und das ist noch unschoener.
		rHTMLWrt.ChangeParaToken( 0 );

		// Alle an dem Node verankerten Rahmen ausgeben
		rHTMLWrt.OutFlyFrm( rNode.GetIndex(), 0, HTML_POS_ANY );

		if( rHTMLWrt.bLFPossible )
			rHTMLWrt.OutNewLine(); // Absatz-Tag in eine neue Zeile

		rHTMLWrt.bLFPossible = sal_True;

		ByteString sOut( '<' );
		sOut += OOO_STRING_SVTOOLS_HTML_horzrule;

		const SfxItemSet* pItemSet = pNd->GetpSwAttrSet();
		if( !pItemSet )
		{
			rWrt.Strm() << sOut.GetBuffer() << '>';
			return rHTMLWrt;
		}
		const SfxPoolItem* pItem;
		if( SFX_ITEM_SET == pItemSet->GetItemState( RES_LR_SPACE, sal_False, &pItem ))
		{
			sal_Int32 nLeft = ((SvxLRSpaceItem*)pItem)->GetLeft();
			sal_Int32 nRight = ((SvxLRSpaceItem*)pItem)->GetRight();
			if( nLeft || nRight )
			{
				const SwFrmFmt& rPgFmt =
                    rHTMLWrt.pDoc->GetPageDescFromPool
                    ( RES_POOLPAGE_HTML, false )->GetMaster();
				const SwFmtFrmSize& rSz   = rPgFmt.GetFrmSize();
				const SvxLRSpaceItem& rLR = rPgFmt.GetLRSpace();
				const SwFmtCol& rCol = rPgFmt.GetCol();

				long nPageWidth = rSz.GetWidth() - rLR.GetLeft() - rLR.GetRight();

				if( 1 < rCol.GetNumCols() )
					nPageWidth /= rCol.GetNumCols();

				const SwTableNode* pTblNd = pNd->FindTableNode();
				if( pTblNd )
				{
					const SwTableBox* pBox = pTblNd->GetTable().GetTblBox(
									pNd->StartOfSectionIndex() );
					if( pBox )
						nPageWidth = pBox->GetFrmFmt()->GetFrmSize().GetWidth();
				}

				((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=';
				rWrt.Strm() << sOut.GetBuffer();
				rWrt.OutULong( rHTMLWrt.ToPixel(nPageWidth-nLeft-nRight) );

				((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=';
				if( !nLeft )
					sOut += OOO_STRING_SVTOOLS_HTML_AL_left;
				else if( !nRight )
					sOut += OOO_STRING_SVTOOLS_HTML_AL_right;
				else
					sOut += OOO_STRING_SVTOOLS_HTML_AL_center;
			}
		}
		rWrt.Strm() << sOut.GetBuffer();
		if( SFX_ITEM_SET == pItemSet->GetItemState( RES_BOX, sal_False, &pItem ))
		{
			const SvxBoxItem* pBoxItem = (const SvxBoxItem*)pItem;
			const SvxBorderLine* pBorderLine = pBoxItem->GetBottom();
			if( pBorderLine )
			{
				sal_uInt16 nWidth = pBorderLine->GetOutWidth() +
								pBorderLine->GetInWidth() +
								pBorderLine->GetDistance();
				((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_size) += '=';
				rWrt.Strm() << sOut.GetBuffer();
				rWrt.OutULong( rHTMLWrt.ToPixel(nWidth) );

				const Color& rBorderColor = pBorderLine->GetColor();
				if( !rBorderColor.IsRGBEqual( Color(COL_GRAY) ) )
				{
					((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_color) += '=';
					rWrt.Strm() << sOut.GetBuffer();
					HTMLOutFuncs::Out_Color( rWrt.Strm(), rBorderColor,
											 rHTMLWrt.eDestEnc );
				}

				if( !pBorderLine->GetInWidth() )
				{
					(sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_noshade;
					rWrt.Strm() << sOut.GetBuffer();
				}
			}
		}
		rWrt.Strm() << '>';
		return rHTMLWrt;
	}

	// Die leeren Nodes mit 2pt Font-Hoehe und der Stand-Vorlage, die
	// vor Tabellen und Bereichen eingefuegt werden, nicht exportieren,
	// Bookmarks oder absatzgebundene Grafiken aber schon.
	// MIB 21.7.97: Ausserdem auch keine leeren Tabellen-Zellen exportieren.
	if( !nEnde && (nPoolId == RES_POOLCOLL_STANDARD ||
				   nPoolId == RES_POOLCOLL_TABLE ||
				   nPoolId == RES_POOLCOLL_TABLE_HDLN) )
	{
		// Der aktuelle Node ist leer und enthaelt Standard-Vorlage ...
		const SfxPoolItem* pItem;
		const SfxItemSet *pItemSet = pNd->GetpSwAttrSet();
		if( pItemSet && pItemSet->Count() &&
			SFX_ITEM_SET == pItemSet->GetItemState( RES_CHRATR_FONTSIZE, sal_False, &pItem ) &&
			40 == ((const SvxFontHeightItem *)pItem)->GetHeight() )
		{
			// ... ausserdem ist die 2pt Schrift eingestellt ...
			sal_uLong nNdPos = rWrt.pCurPam->GetPoint()->nNode.GetIndex();
			const SwNode *pNextNd = rWrt.pDoc->GetNodes()[nNdPos+1];
			const SwNode *pPrevNd = rWrt.pDoc->GetNodes()[nNdPos-1];
			sal_Bool bStdColl = nPoolId == RES_POOLCOLL_STANDARD;
			if( ( bStdColl && (pNextNd->IsTableNode() ||
							   pNextNd->IsSectionNode()) ) ||
				( !bStdColl && pNextNd->IsEndNode() &&
							   pPrevNd->IsStartNode() &&
							   SwTableBoxStartNode==
								pPrevNd->GetStartNode()->GetStartNodeType() ) )
			{
				// ... und er steht vor einer Tabelle ohne einem Bereich
				rHTMLWrt.OutBookmarks();
				rHTMLWrt.bLFPossible = !rHTMLWrt.nLastParaToken;

				// Alle an dem Node verankerten Rahmen ausgeben
				rHTMLWrt.OutFlyFrm( rNode.GetIndex(), 0, HTML_POS_ANY );
				rHTMLWrt.bLFPossible = sal_False;

				return rWrt;
			}
		}
	}

	// PagePreaks uns PagDescs abfangen
	sal_Bool bPageBreakBehind = sal_False;
	if( rHTMLWrt.bCfgFormFeed &&
		!(rHTMLWrt.bOutTable || rHTMLWrt.bOutFlyFrame) &&
		rHTMLWrt.pStartNdIdx->GetIndex() !=
		rHTMLWrt.pCurPam->GetPoint()->nNode.GetIndex() )
	{
		sal_Bool bPageBreakBefore = sal_False;
		const SfxPoolItem* pItem;
		const SfxItemSet* pItemSet = pNd->GetpSwAttrSet();

		if( pItemSet )
		{
			if( SFX_ITEM_SET ==
				pItemSet->GetItemState( RES_PAGEDESC, sal_True, &pItem ) &&
				((SwFmtPageDesc *)pItem)->GetPageDesc() )
				bPageBreakBefore = sal_True;
			else if( SFX_ITEM_SET ==
					 pItemSet->GetItemState( RES_BREAK, sal_True, &pItem ) )
			{
				switch( ((SvxFmtBreakItem *)pItem)->GetBreak() )
				{
				case SVX_BREAK_PAGE_BEFORE:
					bPageBreakBefore = sal_True;
					break;
				case SVX_BREAK_PAGE_AFTER:
					bPageBreakBehind = sal_True;
					break;
				case SVX_BREAK_PAGE_BOTH:
					bPageBreakBefore = sal_True;
					bPageBreakBehind = sal_True;
					break;
				default:
					;
				}
			}
		}

		if( bPageBreakBefore )
			rWrt.Strm() << '\f';
	}

	// eventuell eine Form oeffnen
	rHTMLWrt.OutForm();

	// An dem Node "verankerte" Seitenegebunde Rahmen ausgeben
	sal_Bool bFlysLeft = rHTMLWrt.OutFlyFrm( rNode.GetIndex(),
										 0, HTML_POS_PREFIX );
	// An dem Node verankerte Rahmen ausgeben, die vor dem
	// Absatz-Tag geschrieben werden sollen.
	if( bFlysLeft )
		bFlysLeft = rHTMLWrt.OutFlyFrm( rNode.GetIndex(),
										0, HTML_POS_BEFORE );

	if( rHTMLWrt.pCurPam->GetPoint()->nNode == rHTMLWrt.pCurPam->GetMark()->nNode )
		nEnde = rHTMLWrt.pCurPam->GetMark()->nContent.GetIndex();

	// gibt es harte Attribute, die als Optionen geschrieben werden muessen?
	rHTMLWrt.bTagOn = sal_True;

	// jetzt das Tag des Absatzes ausgeben
	const SwFmt& rFmt = pNd->GetAnyFmtColl();
	SwHTMLTxtCollOutputInfo aFmtInfo;
	sal_Bool bOldLFPossible = rHTMLWrt.bLFPossible;
	OutHTML_SwFmt( rWrt, rFmt, pNd->GetpSwAttrSet(), aFmtInfo );

	// Wenn vor dem Absatz-Tag keine neue Zeile aufgemacht wurde, dann
	// tun wir das jetzt
	rHTMLWrt.bLFPossible = !rHTMLWrt.nLastParaToken;
	if( !bOldLFPossible && rHTMLWrt.bLFPossible )
		rHTMLWrt.OutNewLine();


	// dann die Bookmarks (inkl. End-Tag)
	rHTMLWrt.bOutOpts = sal_False;
	rHTMLWrt.OutBookmarks();

	// jetzt ist noch mal eine gute Gelegenheit fuer ein LF, sofern es noch
	// erlaubt ist
	if( rHTMLWrt.bLFPossible &&
		rHTMLWrt.GetLineLen() >= rHTMLWrt.nWhishLineLen )
	{
		rHTMLWrt.OutNewLine();
	}
	rHTMLWrt.bLFPossible = sal_False;

	// Text, der aus einer Outline-Numerierung kommt ermitteln
	xub_StrLen nOffset = 0;
	String aOutlineTxt;
	String aFullText;
    // --> OD 2006-06-12 #b6435904#
    // export numbering string as plain text only for the outline numbering,
    // because the outline numbering isn't exported as a numbering - see <SwHTMLNumRuleInfo::Set(..)>
    if ( pNd->IsOutline() &&
         pNd->GetNumRule() == pNd->GetDoc()->GetOutlineNumRule() )
    // <--
	{
		aOutlineTxt = pNd->GetNumString();
        nOffset = nOffset + aOutlineTxt.Len();
		aFullText = aOutlineTxt;
	}
	String aFootEndNoteSym;
	if( rHTMLWrt.pFmtFtn )
	{
		aFootEndNoteSym = rHTMLWrt.GetFootEndNoteSym( *rHTMLWrt.pFmtFtn );
        nOffset = nOffset + aFootEndNoteSym.Len();
		aFullText += aFootEndNoteSym;
	}

	// gibt es harte Attribute, die als Tags geschrieben werden muessen?
	aFullText += rStr;
	HTMLEndPosLst aEndPosLst( rWrt.pDoc, rHTMLWrt.pTemplate,
							  rHTMLWrt.pDfltColor, rHTMLWrt.bCfgOutStyles,
							  rHTMLWrt.GetHTMLMode(), aFullText,
						   	  rHTMLWrt.aScriptTextStyles );
	if( aFmtInfo.pItemSet )
	{
		aEndPosLst.Insert( *aFmtInfo.pItemSet, 0, nEnde + nOffset,
						   rHTMLWrt.aChrFmtInfos, sal_False, sal_True );
	}


	if( aOutlineTxt.Len() || rHTMLWrt.pFmtFtn )
	{
		// Absatz-Attribute ausgeben, damit der Text die Attribute des
		// Absatzes bekommt.
		aEndPosLst.OutStartAttrs( rHTMLWrt, 0 );

		// Theoretisch muesste man hier die Zeichen-Vorlage der Numerierung
		// beachten. Da man die ueber die UI nicht setzen kann, ignorieren
		// wir sie erstmal.

		if( aOutlineTxt.Len() )
			HTMLOutFuncs::Out_String( rWrt.Strm(), aOutlineTxt,
								   	  rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters);

		if( rHTMLWrt.pFmtFtn )
		{
			rHTMLWrt.OutFootEndNoteSym( *rHTMLWrt.pFmtFtn, aFootEndNoteSym,
										aEndPosLst.GetScriptAtPos( aOutlineTxt.Len(), rHTMLWrt.nCSS1Script ) );
			rHTMLWrt.pFmtFtn = 0;
		}
	}

	// erstmal den Start berichtigen. D.h. wird nur ein Teil vom Satz
	// ausgegeben, so muessen auch da die Attribute stimmen!!
	rHTMLWrt.bTxtAttr = sal_True;


	sal_uInt16 nAttrPos = 0;
	xub_StrLen nStrPos = rHTMLWrt.pCurPam->GetPoint()->nContent.GetIndex();
	const SwTxtAttr * pHt = 0;
	sal_uInt16 nCntAttr = pNd->HasHints() ? pNd->GetSwpHints().Count() : 0;
	if( nCntAttr && nStrPos > *( pHt = pNd->GetSwpHints()[ 0 ] )->GetStart() )
	{
		// Ok, es gibt vorher Attribute, die ausgegeben werden muessen
		do {
			aEndPosLst.OutEndAttrs( rHTMLWrt, nStrPos + nOffset );

            nAttrPos++;
            if( pHt->Which() == RES_TXTATR_FIELD
                || pHt->Which() == RES_TXTATR_ANNOTATION )
                continue;

            if ( pHt->End() && !pHt->HasDummyChar() )
			{
				const xub_StrLen nHtEnd = *pHt->End(),
					   nHtStt = *pHt->GetStart();
				if( !rHTMLWrt.bWriteAll && nHtEnd <= nStrPos )
					continue;

				// leere Hints am Anfang nicht beachten, oder ??
				if( nHtEnd == nHtStt )
					continue;

				// Attribut in die Liste aufnehemen
				if( rHTMLWrt.bWriteAll )
					aEndPosLst.Insert( pHt->GetAttr(), nHtStt + nOffset,
									   nHtEnd + nOffset,
									   rHTMLWrt.aChrFmtInfos );
				else
				{
					xub_StrLen nTmpStt = nHtStt < nStrPos ? nStrPos : nHtStt;
					xub_StrLen nTmpEnd = nHtEnd < nEnde ? nHtEnd : nEnde;
					aEndPosLst.Insert( pHt->GetAttr(), nTmpStt + nOffset,
									   nTmpEnd + nOffset,
									   rHTMLWrt.aChrFmtInfos );
				}
				continue;
				// aber nicht ausgeben, das erfolgt spaeter !!
			}

		} while( nAttrPos < nCntAttr && nStrPos >
			*( pHt = pNd->GetSwpHints()[ nAttrPos ] )->GetStart() );

		// dann gebe mal alle gesammelten Attribute von der String-Pos aus
		aEndPosLst.OutEndAttrs( rHTMLWrt, nStrPos + nOffset );
		aEndPosLst.OutStartAttrs( rHTMLWrt, nStrPos + nOffset );
	}

	sal_Bool bWriteBreak = (HTML_PREFORMTXT_ON != rHTMLWrt.nLastParaToken);
	if( bWriteBreak && pNd->GetNumRule()  )
		bWriteBreak = sal_False;

	{
		HTMLOutContext aContext( rHTMLWrt.eDestEnc );

		xub_StrLen nPreSplitPos = 0;
		for( ; nStrPos < nEnde; nStrPos++ )
		{
			aEndPosLst.OutEndAttrs( rHTMLWrt, nStrPos + nOffset, &aContext );

			// Die an der aktuellen Position verankerten Rahmen ausgeben
			if( bFlysLeft )
				bFlysLeft =	rHTMLWrt.OutFlyFrm( rNode.GetIndex(),
												nStrPos, HTML_POS_INSIDE,
												&aContext );

			sal_Bool bOutChar = sal_True;
			const SwTxtAttr * pTxtHt = 0;
			if( nAttrPos < nCntAttr && *pHt->GetStart() == nStrPos
				&& nStrPos != nEnde )
			{
				do {
                    if ( pHt->End() && !pHt->HasDummyChar() )
					{
						if( RES_CHRATR_KERNING == pHt->Which() &&
							rHTMLWrt.IsHTMLMode(HTMLMODE_FIRSTLINE) &&
							*pHt->End() - nStrPos == 1 &&
							' ' == rStr.GetChar(nStrPos) &&
							((const SvxKerningItem&)pHt->GetAttr()).GetValue() > 0 )
						{
							// Wenn erlaubt, wird das Ding als Spacer exportiert

							bOutChar = sal_False;	// Space nicht ausgeben
							bWriteBreak = sal_False;	// der Absatz ist aber auch nicht leer
							HTMLOutFuncs::FlushToAscii( rWrt.Strm(), aContext );
							OutHTML_HoriSpacer( rWrt,
								((const SvxKerningItem&)pHt->GetAttr()).GetValue() );

							// Der Hint braucht nun doch nicht weiter
							// beruecksichtigt werden.
						}
						else if( *pHt->End() != nStrPos )
						{
							// Hints mit Ende einsortieren, wenn sie keinen
							// leeren Bereich aufspannen (Hints, die keinen
							// Bereich aufspannen werden ignoriert
							aEndPosLst.Insert( pHt->GetAttr(), nStrPos + nOffset,
											   *pHt->End() + nOffset,
											   rHTMLWrt.aChrFmtInfos );
						}
					}
					else
					{
                        // Hints ohne-Ende werden als letztes ausgebeben
                        ASSERT( !pTxtHt, "Wieso gibt es da schon ein Attribut ohne Ende?" );
                        if( rHTMLWrt.nTxtAttrsToIgnore>0 )
                        {
                            rHTMLWrt.nTxtAttrsToIgnore--;
                        }
                        else
                        {
                            pTxtHt = pHt;
                            sal_uInt16 nFldWhich;
                            if( RES_TXTATR_FIELD != pHt->Which()
                                || ( RES_POSTITFLD != (nFldWhich = ((const SwFmtFld&)pHt->GetAttr()).GetField()->Which())
                                     && RES_SCRIPTFLD != nFldWhich ) )
                            {
                                bWriteBreak = sal_False;
                            }
                        }
                        bOutChar = sal_False;		// keine 255 ausgeben
                    }
				} while( ++nAttrPos < nCntAttr && nStrPos ==
					*( pHt = pNd->GetSwpHints()[ nAttrPos ] )->GetStart() );
			}

			// Manche Draw-Formate koennen auch noch Attribute mitbringen
			if( pTxtHt && RES_TXTATR_FLYCNT == pTxtHt->Which() )
			{
				const SwFrmFmt* pFrmFmt =
					((const SwFmtFlyCnt &)pTxtHt->GetAttr()).GetFrmFmt();

				if( RES_DRAWFRMFMT == pFrmFmt->Which() )
					aEndPosLst.Insert( *((const SwDrawFrmFmt *)pFrmFmt),
										nStrPos + nOffset,
										rHTMLWrt.aChrFmtInfos );
			}

			aEndPosLst.OutEndAttrs( rHTMLWrt, nStrPos + nOffset, &aContext );
			aEndPosLst.OutStartAttrs( rHTMLWrt, nStrPos + nOffset, &aContext );

			if( pTxtHt )
			{
				rHTMLWrt.bLFPossible = !rHTMLWrt.nLastParaToken && nStrPos > 0 &&
									   rStr.GetChar(nStrPos-1) == ' ';
				sal_uInt16 nCSS1Script = rHTMLWrt.nCSS1Script;
				rHTMLWrt.nCSS1Script = aEndPosLst.GetScriptAtPos(
												nStrPos + nOffset, nCSS1Script );
				HTMLOutFuncs::FlushToAscii( rWrt.Strm(), aContext );
				Out( aHTMLAttrFnTab, pTxtHt->GetAttr(), rHTMLWrt );
				rHTMLWrt.nCSS1Script = nCSS1Script;
				rHTMLWrt.bLFPossible = sal_False;
			}

			if( bOutChar )
			{
				// #i120442#: get the UTF-32 codepoint by converting an eventual UTF-16 unicode surrogate pair
				sal_uInt64 c = rStr.GetChar( nStrPos );
				if( nStrPos < nEnde - 1 )
				{
					const sal_Unicode d = rStr.GetChar( nStrPos + 1 );
					if( (c >= 0xd800 && c <= 0xdbff) && (d >= 0xdc00 && d <= 0xdfff) )
					{
						sal_uInt64 templow = d&0x03ff;
						sal_uInt64 temphi = ((c&0x03ff) + 0x0040)<<10;
						c = temphi|templow;
						nStrPos++;
					}
				}
				
				// try to split a line after about 255 characters
				// at a space character unless in a PRE-context
				if( ' '==c && !rHTMLWrt.nLastParaToken  )
				{
					xub_StrLen nLineLen;
					if( rHTMLWrt.nLastParaToken )
						nLineLen = nStrPos - nPreSplitPos;
					else
						nLineLen = rHTMLWrt.GetLineLen();

					xub_StrLen nWordLen = rStr.Search( ' ', nStrPos+1 );
					if( nWordLen == STRING_NOTFOUND )
						nWordLen = nEnde;
					nWordLen -= nStrPos;

					if( nLineLen >= rHTMLWrt.nWhishLineLen ||
						(nLineLen+nWordLen) >= rHTMLWrt.nWhishLineLen )
					{
						HTMLOutFuncs::FlushToAscii( rWrt.Strm(), aContext );
						rHTMLWrt.OutNewLine();
						bOutChar = sal_False;
						if( rHTMLWrt.nLastParaToken )
							nPreSplitPos = nStrPos+1;
					}
				}

				if( bOutChar )
				{
					if( 0x0a == c )
					{
						HTMLOutFuncs::FlushToAscii( rWrt.Strm(), aContext );
						HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_linebreak );
					}
					// #i120442#: if c is outside the unicode base plane output it as "&#******;"
					else if( c > 0xffff)
					{
						ByteString sOut("&#");
						sOut += ByteString::CreateFromInt64( (sal_uInt64)c );
						sOut += ';';
						rWrt.Strm() << sOut.GetBuffer();
					}
					else
						HTMLOutFuncs::Out_Char( rWrt.Strm(), (sal_Unicode)c, aContext, &rHTMLWrt.aNonConvertableCharacters );

					// if a paragraph's last character is a hard line break
					// then we need to add an extra <br>
					// because browsers like Mozilla wouldn't add a line for the next paragraph
					bWriteBreak = (0x0a == c) &&
								  (HTML_PREFORMTXT_ON != rHTMLWrt.nLastParaToken);
				}
			}
		}
		HTMLOutFuncs::FlushToAscii( rWrt.Strm(), aContext );
	}

	aEndPosLst.OutEndAttrs( rHTMLWrt, STRING_MAXLEN );

	// Die an der letzten Position verankerten Rahmen ausgeben
	if( bFlysLeft )
		bFlysLeft = rHTMLWrt.OutFlyFrm( rNode.GetIndex(),
									   nEnde, HTML_POS_INSIDE );
	ASSERT( !bFlysLeft, "Es wurden nicht alle Rahmen gespeichert!" );

	rHTMLWrt.bTxtAttr = sal_False;

	if( bWriteBreak )
	{
		sal_Bool bEndOfCell = rHTMLWrt.bOutTable &&
						 rWrt.pCurPam->GetPoint()->nNode.GetIndex() ==
						 rWrt.pCurPam->GetMark()->nNode.GetIndex();

		if( bEndOfCell && !nEnde &&
			rHTMLWrt.IsHTMLMode(HTMLMODE_NBSP_IN_TABLES) )
		{
			// Wenn der letzte Absatz einer Tabellezelle leer ist und
			// wir fuer den MS-IE exportieren, schreiben wir statt eines
			// <BR> ein &nbsp;
			rWrt.Strm() << '&' << OOO_STRING_SVTOOLS_HTML_S_nbsp << ';';
		}
		else
		{
			HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_linebreak );
			const SvxULSpaceItem& rULSpace =
				(const SvxULSpaceItem &)pNd->GetSwAttrSet().Get(RES_UL_SPACE);
			if( rULSpace.GetLower() > 0 && !bEndOfCell &&
				!rHTMLWrt.IsHTMLMode(HTMLMODE_NO_BR_AT_PAREND) )
				HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_linebreak );
			rHTMLWrt.bLFPossible = sal_True;
		}
	}

	if( rHTMLWrt.bClearLeft || rHTMLWrt.bClearRight )
	{
		const sal_Char *pStr;
		if( rHTMLWrt.bClearLeft )
		{
			if( rHTMLWrt.bClearRight )
				pStr = OOO_STRING_SVTOOLS_HTML_AL_all;
			else
				pStr = OOO_STRING_SVTOOLS_HTML_AL_left;
		}
		else
			pStr = OOO_STRING_SVTOOLS_HTML_AL_right;

		ByteString sOut( OOO_STRING_SVTOOLS_HTML_linebreak );
		(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_clear) += '=') += pStr;

		HTMLOutFuncs::Out_AsciiTag( rHTMLWrt.Strm(), sOut.GetBuffer() );
		rHTMLWrt.bClearLeft = sal_False;
		rHTMLWrt.bClearRight = sal_False;

		rHTMLWrt.bLFPossible = sal_True;
	}

	// wenn ein LF nicht schon erlaubt ist wird es erlaubt, wenn der
	// Absatz mit einem ' ' endet
	if( !rHTMLWrt.bLFPossible && !rHTMLWrt.nLastParaToken &&
		nEnde > 0 && ' ' == rStr.GetChar(nEnde-1) )
		rHTMLWrt.bLFPossible = sal_True;

	rHTMLWrt.bTagOn = sal_False;
	OutHTML_SwFmtOff( rWrt, aFmtInfo );

	// eventuell eine Form schliessen
	rHTMLWrt.OutForm( sal_False );

	if( bPageBreakBehind )
		rWrt.Strm() << '\f';

	return rHTMLWrt;
}


sal_uInt32 SwHTMLWriter::ToPixel( sal_uInt32 nVal ) const
{
	if( Application::GetDefaultDevice() && nVal )
	{
		nVal = Application::GetDefaultDevice()->LogicToPixel(
					Size( nVal, nVal ), MapMode( MAP_TWIP ) ).Width();
		if( !nVal )		// wo ein Twip ist sollte auch ein Pixel sein
			nVal = 1;
	}
	return nVal;
}


static Writer& OutHTML_CSS1Attr( Writer& rWrt, const SfxPoolItem& rHt )
{
	// wenn gerade Hints geschrieben werden versuchen wir den Hint als
	// CSS1-Attribut zu schreiben

	if( ((SwHTMLWriter&)rWrt).bCfgOutStyles && ((SwHTMLWriter&)rWrt).bTxtAttr )
		OutCSS1_HintSpanTag( rWrt, rHt );

	return rWrt;
}


/* File CHRATR.HXX: */

static Writer& OutHTML_SvxColor( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
	if( rHTMLWrt.bOutOpts )
		return rWrt;

	// die Default-Farbe nur Schreiben, wenn sie als Hint vorkommt
	//if( rHTMLWrt.bTagOn && !rHTMLWrt.bTxtAttr && rHTMLWrt.pDfltColor
	//	&& rColor == *rHTMLWrt.pDfltColor )
	//	return rWrt;

	if( !rHTMLWrt.bTxtAttr && rHTMLWrt.bCfgOutStyles && rHTMLWrt.bCfgPreferStyles )
	{
		// Font-Farbe nicht als Tag schreiben, wenn Styles normalen Tags
		// vorgezogen werden
		return rWrt;
	}

	if( rHTMLWrt.bTagOn )
	{
		Color aColor( ((const SvxColorItem&)rHt).GetValue() );
		if( COL_AUTO == aColor.GetColor() )
			aColor.SetColor( COL_BLACK );

		ByteString sOut( '<' );
		(((sOut += OOO_STRING_SVTOOLS_HTML_font) += ' ') += OOO_STRING_SVTOOLS_HTML_O_color) += '=';
		rWrt.Strm() << sOut.GetBuffer();
		HTMLOutFuncs::Out_Color( rWrt.Strm(), aColor, rHTMLWrt.eDestEnc ) << '>';
	}
	else
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_font, sal_False );

	return rWrt;
}


static Writer& OutHTML_SwPosture( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
	if( rHTMLWrt.bOutOpts )
		return rWrt;

	const FontItalic nPosture = ((const SvxPostureItem&)rHt).GetPosture();
	if( ITALIC_NORMAL == nPosture )
	{
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_italic, rHTMLWrt.bTagOn );
	}
	else if( rHTMLWrt.bCfgOutStyles && rHTMLWrt.bTxtAttr )
	{
		// vielleicht als CSS1-Attribut ?
		OutCSS1_HintSpanTag( rWrt, rHt );
	}

	return rWrt;
}

static Writer& OutHTML_SvxFont( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
	if( rHTMLWrt.bOutOpts )
		return rWrt;

	if( rHTMLWrt.bTagOn )
	{
		String aNames;
		SwHTMLWriter::PrepareFontList( ((const SvxFontItem&)rHt), aNames, 0,
						   rHTMLWrt.IsHTMLMode(HTMLMODE_FONT_GENERIC) );
		ByteString sOut( '<' );
		(((sOut += OOO_STRING_SVTOOLS_HTML_font) += ' ') += OOO_STRING_SVTOOLS_HTML_O_face) += "=\"";
		rWrt.Strm() << sOut.GetBuffer();
		HTMLOutFuncs::Out_String( rWrt.Strm(), aNames, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters )
			<< "\">";
	}
	else
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_font , sal_False );

	return rWrt;
}

static Writer& OutHTML_SvxFontHeight( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
	if( rHTMLWrt.bOutOpts )
		return rWrt;

	if( rHTMLWrt.bTagOn )
	{
		ByteString sOut( '<' );
		sOut += OOO_STRING_SVTOOLS_HTML_font;

		sal_uInt32 nHeight = ((const SvxFontHeightItem&)rHt).GetHeight();
		sal_uInt16 nSize = rHTMLWrt.GetHTMLFontSize( nHeight );
		(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_size) += '=')
			+= ByteString::CreateFromInt32( nSize );
		rWrt.Strm() << sOut.GetBuffer();

		if( rHTMLWrt.bCfgOutStyles && rHTMLWrt.bTxtAttr &&
			rHTMLWrt.aFontHeights[nSize-1] != nHeight )
		{
			// wenn die Groesse keiner HTML-Groesse entspricht,
			// wird sie noch zusatzlich als Style-Option exportiert
			OutCSS1_HintStyleOpt( rWrt, rHt );
		}
		rWrt.Strm() << '>';
	}
	else
	{
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_font, sal_False );
	}

	return rWrt;
}

static Writer& OutHTML_SvxLanguage( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
	if( rHTMLWrt.bOutOpts )
		return rWrt;

	LanguageType eLang = ((const SvxLanguageItem &)rHt).GetLanguage();
	if( LANGUAGE_DONTKNOW == eLang )
		return rWrt;

	if( rHTMLWrt.bTagOn )
	{
		ByteString sOut( '<' );
		sOut += OOO_STRING_SVTOOLS_HTML_span;
		rWrt.Strm() << sOut.GetBuffer();
		rHTMLWrt.OutLanguage( ((const SvxLanguageItem &)rHt).GetLanguage() );
		rWrt.Strm() << '>';
	}
	else
	{
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_span, sal_False );
	}

	return rWrt;
}
static Writer& OutHTML_SwWeight( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
	if( rHTMLWrt.bOutOpts )
		return rWrt;

	const FontWeight nBold = ((const SvxWeightItem&)rHt).GetWeight();
	if( WEIGHT_BOLD == nBold )
	{
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_bold, rHTMLWrt.bTagOn );
	}
	else if( rHTMLWrt.bCfgOutStyles && rHTMLWrt.bTxtAttr )
	{
		// vielleicht als CSS1-Attribut ?
		OutCSS1_HintSpanTag( rWrt, rHt );
	}

	return rWrt;
}


static Writer& OutHTML_SwCrossedOut( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
	if( rHTMLWrt.bOutOpts )
		return rWrt;

	// Wegen Netscape schrieben wir hier STRIKE und nicht S raus!
	const FontStrikeout nStrike = ((const SvxCrossedOutItem&)rHt).GetStrikeout();
	if( STRIKEOUT_NONE != nStrike )
	{
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_strike, rHTMLWrt.bTagOn );
	}
	else if( rHTMLWrt.bCfgOutStyles && rHTMLWrt.bTxtAttr )
	{
		// vielleicht als CSS1-Attribut ?
		OutCSS1_HintSpanTag( rWrt, rHt );
	}

	return rWrt;
}


static Writer& OutHTML_SvxEscapement( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
	if( rHTMLWrt.bOutOpts )
		return rWrt;

	const SvxEscapement eEscape =
		(const SvxEscapement)((const SvxEscapementItem&)rHt).GetEnumValue();
	const sal_Char *pStr = 0;
	switch( eEscape )
	{
	case SVX_ESCAPEMENT_SUPERSCRIPT: pStr = OOO_STRING_SVTOOLS_HTML_superscript; break;
	case SVX_ESCAPEMENT_SUBSCRIPT: pStr = OOO_STRING_SVTOOLS_HTML_subscript; break;
	default:
		;
	}

	if( pStr )
	{
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), pStr, rHTMLWrt.bTagOn );
	}
	else if( rHTMLWrt.bCfgOutStyles && rHTMLWrt.bTxtAttr )
	{
		// vielleicht als CSS1-Attribut ?
		OutCSS1_HintSpanTag( rWrt, rHt );
	}

	return rWrt;
}



static Writer& OutHTML_SwUnderline( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
	if( rHTMLWrt.bOutOpts )
		return rWrt;

	const FontUnderline eUnder = ((const SvxUnderlineItem&)rHt).GetLineStyle();
	if( UNDERLINE_NONE != eUnder )
	{
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_underline, rHTMLWrt.bTagOn );
	}
	else if( rHTMLWrt.bCfgOutStyles && rHTMLWrt.bTxtAttr )
	{
		// vielleicht als CSS1-Attribut ?
		OutCSS1_HintSpanTag( rWrt, rHt );
	}

	return rWrt;
}


static Writer& OutHTML_SwFlyCnt( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
	SwFmtFlyCnt& rFlyCnt = (SwFmtFlyCnt&)rHt;

	const SwFrmFmt& rFmt = *rFlyCnt.GetFrmFmt();
	const SdrObject *pSdrObj = 0;

	SwHTMLFrmType eType =
		(SwHTMLFrmType)rHTMLWrt.GuessFrmType( rFmt, pSdrObj );
	sal_uInt8 nMode = aHTMLOutFrmAsCharTable[eType][rHTMLWrt.nExportMode];
	rHTMLWrt.OutFrmFmt( nMode, rFmt, pSdrObj );
	return rWrt;
}


// Das ist jetzt unser Blink-Item. Blinkend wird eingeschaltet, indem man
// das Item auf sal_True setzt!
static Writer& OutHTML_SwBlink( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
	if( rHTMLWrt.bOutOpts || !rHTMLWrt.IsHTMLMode(HTMLMODE_BLINK) )
		return rWrt;

	if( ((const SvxBlinkItem&)rHt).GetValue() )
	{
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_blink, rHTMLWrt.bTagOn );
	}
	else if( rHTMLWrt.bCfgOutStyles && rHTMLWrt.bTxtAttr )
	{
		// vielleicht als CSS1-Attribut ?
		OutCSS1_HintSpanTag( rWrt, rHt );
	}

	return rWrt;
}

Writer& OutHTML_INetFmt( Writer& rWrt, const SwFmtINetFmt& rINetFmt, sal_Bool bOn )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	String aURL( rINetFmt.GetValue() );
	const SvxMacroTableDtor *pMacTable = rINetFmt.GetMacroTbl();
	sal_Bool bEvents = pMacTable != 0 && pMacTable->Count() > 0;

	// Gibt es ueberhaupt etwas auszugeben?
	if( !aURL.Len() && !bEvents && !rINetFmt.GetName().Len() )
		return rWrt;

	// Tag aus? Dann nur ein </A> ausgeben.
	if( !bOn )
	{
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_anchor, sal_False );
		return rWrt;
	}

	ByteString sOut( '<' );
	sOut += OOO_STRING_SVTOOLS_HTML_anchor;

	sal_Bool bScriptDependent = sal_False;
	{
		const SwCharFmt* pFmt = rWrt.pDoc->GetCharFmtFromPool(
				 RES_POOLCHR_INET_NORMAL );
		SwHTMLFmtInfo aFmtInfo( pFmt );
		sal_uInt16 nPos;
		if( rHTMLWrt.aChrFmtInfos.Seek_Entry( &aFmtInfo, &nPos ) )
		{
			bScriptDependent = rHTMLWrt.aChrFmtInfos[nPos]->bScriptDependent;
		}
	}
	if( !bScriptDependent )
	{
		const SwCharFmt* pFmt = rWrt.pDoc->GetCharFmtFromPool(
				 RES_POOLCHR_INET_VISIT );
		SwHTMLFmtInfo aFmtInfo( pFmt );
		sal_uInt16 nPos;
		if( rHTMLWrt.aChrFmtInfos.Seek_Entry( &aFmtInfo, &nPos ) )
		{
			bScriptDependent = rHTMLWrt.aChrFmtInfos[nPos]->bScriptDependent;
		}
	}

	if( bScriptDependent )
	{
		((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_class) += "=\"";
		switch( rHTMLWrt.nCSS1Script )
		{
		case CSS1_OUTMODE_WESTERN:
			sOut += "western";
			break;
		case CSS1_OUTMODE_CJK:
			sOut += "cjk";
			break;
		case CSS1_OUTMODE_CTL:
			sOut += "ctl";
			break;
		}
		sOut += '\"';
	}

	rWrt.Strm() << sOut.GetBuffer();

#define REL_HACK
#ifdef REL_HACK
	String sRel;
#endif

	if( aURL.Len() || bEvents )
	{
#ifdef REL_HACK
		String sTmp( aURL );
		sTmp.ToUpperAscii();
		xub_StrLen nPos = sTmp.SearchAscii( "\" REL=" );
		if( nPos!=STRING_NOTFOUND )
		{
			sRel = aURL.Copy( nPos+1 );
			aURL.Erase( nPos );
		}
#endif
		aURL.EraseLeadingChars().EraseTrailingChars();

		((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_href) += "=\"";
		rWrt.Strm() << sOut.GetBuffer();
		rHTMLWrt.OutHyperlinkHRefValue( aURL );
		sOut = '\"';
	}
	else
		sOut.Erase();

	if( rINetFmt.GetName().Len() )
	{
		((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_name) += "=\"";
		rWrt.Strm() << sOut.GetBuffer();
		HTMLOutFuncs::Out_String( rWrt.Strm(), rINetFmt.GetName(),
								  rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
		sOut = '\"';
	}

	const String& rTarget = rINetFmt.GetTargetFrame();
	if( rTarget.Len() )
	{
		((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_target) += "=\"";
		rWrt.Strm() << sOut.GetBuffer();
		HTMLOutFuncs::Out_String( rWrt.Strm(), rTarget, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
		sOut = '\"';
	}

#ifdef REL_HACK
	if( sRel.Len() )
		sOut += ByteString( sRel, RTL_TEXTENCODING_ASCII_US );
#endif
	if( sOut.Len() )
		rWrt.Strm() << sOut.GetBuffer();

	if( bEvents )
		HTMLOutFuncs::Out_Events( rWrt.Strm(), *pMacTable, aAnchorEventTable,
								  rHTMLWrt.bCfgStarBasic, rHTMLWrt.eDestEnc,
							   	  &rHTMLWrt.aNonConvertableCharacters	);
	rWrt.Strm() << ">";

	return rWrt;
}

static Writer& OutHTML_SwFmtINetFmt( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;

	if( rHTMLWrt.bOutOpts )
		return rWrt;

	const SwFmtINetFmt& rINetFmt = (const SwFmtINetFmt&)rHt;

	if( rHTMLWrt.bTagOn )
	{
		// ggf. ein noch offenes Attribut voruebergehend beenden
		if( rHTMLWrt.aINetFmts.Count() )
		{
			SwFmtINetFmt *pINetFmt =
				rHTMLWrt.aINetFmts[ rHTMLWrt.aINetFmts.Count()-1 ];
			OutHTML_INetFmt( rWrt, *pINetFmt, sal_False );
		}

		// jetzt das neue aufmachen
		OutHTML_INetFmt( rWrt, rINetFmt, sal_True );

		// und merken
		const SwFmtINetFmt *pINetFmt = new SwFmtINetFmt( rINetFmt );
		rHTMLWrt.aINetFmts.C40_INSERT( SwFmtINetFmt, pINetFmt,
									   rHTMLWrt.aINetFmts.Count() );
	}
	else
	{
		// das
		OutHTML_INetFmt( rWrt, rINetFmt, sal_False );

		ASSERT( rHTMLWrt.aINetFmts.Count(), "da fehlt doch ein URL-Attribut" );
		if( rHTMLWrt.aINetFmts.Count() )
		{
			// das eigene Attribut vom Stack holen
			SwFmtINetFmt *pINetFmt =
				rHTMLWrt.aINetFmts[ rHTMLWrt.aINetFmts.Count()-1 ];

			rHTMLWrt.aINetFmts.Remove( rHTMLWrt.aINetFmts.Count()-1, 1 );
			delete pINetFmt;
		}

		if( rHTMLWrt.aINetFmts.Count() )
		{
			// es ist noch ein Attribut auf dem Stack, das wieder geoeffnet
			// werden muss
			SwFmtINetFmt *pINetFmt =
				rHTMLWrt.aINetFmts[ rHTMLWrt.aINetFmts.Count()-1 ];
			OutHTML_INetFmt( rWrt, *pINetFmt, sal_True );
		}
	}

	return rWrt;
}

static Writer& OutHTML_SwTxtCharFmt( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
	if( rHTMLWrt.bOutOpts )
		return rWrt;

	const SwFmtCharFmt& rChrFmt = (const SwFmtCharFmt&)rHt;
	const SwCharFmt* pFmt = rChrFmt.GetCharFmt();

	if( !pFmt )
	{
		return rWrt;
	}

	SwHTMLFmtInfo aFmtInfo( pFmt );
	sal_uInt16 nPos;
	if( !rHTMLWrt.aChrFmtInfos.Seek_Entry( &aFmtInfo, &nPos ) )
		return rWrt;

	const SwHTMLFmtInfo *pFmtInfo = rHTMLWrt.aChrFmtInfos[nPos];
	ASSERT( pFmtInfo, "Wieso gint es keine Infos ueber die Zeichenvorlage?" );

	if( rHTMLWrt.bTagOn )
	{
		ByteString sOut( '<' );
		if( pFmtInfo->aToken.Len() > 0 )
			sOut += pFmtInfo->aToken;
		else
			sOut += OOO_STRING_SVTOOLS_HTML_span;
		if( rHTMLWrt.bCfgOutStyles &&
			(pFmtInfo->aClass.Len() || pFmtInfo->bScriptDependent) )
		{
			((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_class) += "=\"";
			rWrt.Strm() << sOut.GetBuffer();
			String aClass( pFmtInfo->aClass );
			if( pFmtInfo->bScriptDependent )
			{
				if( aClass.Len() )
				   aClass += '-';
				switch( rHTMLWrt.nCSS1Script )
				{
				case CSS1_OUTMODE_WESTERN:
					aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("western") );
					break;
				case CSS1_OUTMODE_CJK:
					aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("cjk") );
					break;
				case CSS1_OUTMODE_CTL:
					aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("ctl") );
					break;
				}
			}
			HTMLOutFuncs::Out_String( rWrt.Strm(), aClass,
						  		  	  rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
			sOut = '\"';
		}
		sOut += '>';
		rWrt.Strm() << sOut.GetBuffer();
	}
	else
	{
		HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
				pFmtInfo->aToken.Len() ? pFmtInfo->aToken.GetBuffer()
									   : OOO_STRING_SVTOOLS_HTML_span,
				sal_False );
	}

	return rWrt;
}

static Writer& OutHTML_SvxAdjust( Writer& rWrt, const SfxPoolItem& rHt )
{
	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
	if( !rHTMLWrt.bOutOpts || !rHTMLWrt.bTagOn )
		return  rWrt;

	SvxAdjustItem& rAdjust = (SvxAdjustItem&)rHt;
	const sal_Char* pStr = 0;
	switch( rAdjust.GetAdjust() )
	{
	case SVX_ADJUST_CENTER: pStr = OOO_STRING_SVTOOLS_HTML_AL_center; break;
	case SVX_ADJUST_LEFT: pStr = OOO_STRING_SVTOOLS_HTML_AL_left; break;
	case SVX_ADJUST_RIGHT: pStr = OOO_STRING_SVTOOLS_HTML_AL_right; break;
	case SVX_ADJUST_BLOCK: pStr = OOO_STRING_SVTOOLS_HTML_AL_justify; break;
	default:
		;
	}
	if( pStr )
	{
		ByteString sOut( ' ' );
		((sOut += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += pStr;
		rWrt.Strm() << sOut.GetBuffer();
	}

	return rWrt;
}

/*
 * lege hier die Tabellen fuer die HTML-Funktions-Pointer auf
 * die Ausgabe-Funktionen an.
 * Es sind lokale Strukturen, die nur innerhalb der HTML-DLL
 * bekannt sein muessen.
 */


SwAttrFnTab aHTMLAttrFnTab = {
/* RES_CHRATR_CASEMAP	*/          OutHTML_CSS1Attr,
/* RES_CHRATR_CHARSETCOLOR	*/      0,
/* RES_CHRATR_COLOR	*/              OutHTML_SvxColor,
/* RES_CHRATR_CONTOUR	*/          0,
/* RES_CHRATR_CROSSEDOUT	*/      OutHTML_SwCrossedOut,
/* RES_CHRATR_ESCAPEMENT	*/      OutHTML_SvxEscapement,
/* RES_CHRATR_FONT	*/              OutHTML_SvxFont,
/* RES_CHRATR_FONTSIZE	*/          OutHTML_SvxFontHeight,
/* RES_CHRATR_KERNING	*/          OutHTML_CSS1Attr,
/* RES_CHRATR_LANGUAGE	*/          OutHTML_SvxLanguage,
/* RES_CHRATR_POSTURE	*/          OutHTML_SwPosture,
/* RES_CHRATR_PROPORTIONALFONTSIZE*/0,
/* RES_CHRATR_SHADOWED	*/          0,
/* RES_CHRATR_UNDERLINE	*/          OutHTML_SwUnderline,
/* RES_CHRATR_WEIGHT	*/          OutHTML_SwWeight,
/* RES_CHRATR_WORDLINEMODE	*/      0,
/* RES_CHRATR_AUTOKERN	*/          0,
/* RES_CHRATR_BLINK	*/          	OutHTML_SwBlink,
/* RES_CHRATR_NOHYPHEN	*/          0, // Neu: nicht trennen
/* RES_CHRATR_NOLINEBREAK */        0, // Neu: nicht umbrechen
/* RES_CHRATR_BACKGROUND */        	OutHTML_CSS1Attr, // Neu: Zeichenhintergrund
/* RES_CHRATR_CJK_FONT */			OutHTML_SvxFont,
/* RES_CHRATR_CJK_FONTSIZE */		OutHTML_SvxFontHeight,
/* RES_CHRATR_CJK_LANGUAGE */		OutHTML_SvxLanguage,
/* RES_CHRATR_CJK_POSTURE */		OutHTML_SwPosture,
/* RES_CHRATR_CJK_WEIGHT */			OutHTML_SwWeight,
/* RES_CHRATR_CTL_FONT */			OutHTML_SvxFont,
/* RES_CHRATR_CTL_FONTSIZE */		OutHTML_SvxFontHeight,
/* RES_CHRATR_CTL_LANGUAGE */		OutHTML_SvxLanguage,
/* RES_CHRATR_CTL_POSTURE */		OutHTML_SwPosture,
/* RES_CHRATR_CTL_WEIGHT */			OutHTML_SwWeight,
/* RES_CHRATR_ROTATE */             0,
/* RES_CHRATR_EMPHASIS_MARK */      0,
/* RES_CHRATR_TWO_LINES */          0,
/* RES_CHRATR_SCALEW */             0,
/* RES_CHRATR_RELIEF */             0,
/* RES_CHRATR_HIDDEN */             0,
/* RES_CHRATR_OVERLINE */           OutHTML_CSS1Attr,
/* RES_CHRATR_DUMMY1 */             0,
/* RES_CHRATR_DUMMY2 */             0,
//For i120935, Insert blank entry for RES_CHRATR_BIDITRL and RES_CHRATR_IDCTHINT, for keep the identical res order
/*RES_CHRATR_BIDIRTL*/			0,
/*RES_CHRATR_IDCTHINT*/		0,
/* RES_TXTATR_REFMARK */            0,
/* RES_TXTATR_TOXMARK */            0,
/* RES_TXTATR_META */               0,
/* RES_TXTATR_METAFIELD */          0,
/* RES_TXTATR_AUTOFMT */            0,
/* RES_TXTATR_INETFMT */            OutHTML_SwFmtINetFmt,
/* RES_TXTATR_CHARFMT */            OutHTML_SwTxtCharFmt,
/* RES_TXTATR_CJK_RUBY */           0,
/* RES_TXTATR_UNKNOWN_CONTAINER */  0,
/* RES_TXTATR_INPUTFIELD */         OutHTML_SwFmtFld,

/* RES_TXTATR_FIELD */              OutHTML_SwFmtFld,
/* RES_TXTATR_FLYCNT */             OutHTML_SwFlyCnt,
/* RES_TXTATR_FTN */                OutHTML_SwFmtFtn,
/* RES_TXTATR_ANNOTATION */         OutHTML_SwFmtFld,
/* RES_TXTATR_DUMMY3 */             0,
/* RES_TXTATR_DUMMY1 */             0, // Dummy:
/* RES_TXTATR_DUMMY2 */             0, // Dummy:

/* RES_PARATR_LINESPACING	*/      0,
/* RES_PARATR_ADJUST	*/          OutHTML_SvxAdjust,
/* RES_PARATR_SPLIT	*/				0,
/* RES_PARATR_WIDOWS	*/          0,
/* RES_PARATR_ORPHANS	*/          0,
/* RES_PARATR_TABSTOP	*/          0,
/* RES_PARATR_HYPHENZONE*/          0,
/* RES_PARATR_DROP */				OutHTML_CSS1Attr,
/* RES_PARATR_REGISTER */        	0, // neu:  Registerhaltigkeit
/* RES_PARATR_NUMRULE */      	    0, // Dummy:
/* RES_PARATR_SCRIPTSPACE */   	    0, // Dummy:
/* RES_PARATR_HANGINGPUNCTUATION */	0, // Dummy:
/* RES_PARATR_FORBIDDEN_RULES */    0, // new
/* RES_PARATR_VERTALIGN */          0, // new
/* RES_PARATR_SNAPTOGRID*/          0, // new
/* RES_PARATR_CONNECT_TO_BORDER */  0, // new

/* RES_PARATR_LIST_ID */            0, // new
/* RES_PARATR_LIST_LEVEL */         0, // new
/* RES_PARATR_LIST_ISRESTART */     0, // new
/* RES_PARATR_LIST_RESTARTVALUE */  0, // new
/* RES_PARATR_LIST_ISCOUNTED */     0, // new

/* RES_FILL_ORDER	*/				0,
/* RES_FRM_SIZE	*/					0,
/* RES_PAPER_BIN	*/              0,
/* RES_LR_SPACE	*/                  0,
/* RES_UL_SPACE	*/                  0,
/* RES_PAGEDESC */					0,
/* RES_BREAK */						0,
/* RES_CNTNT */						0,
/* RES_HEADER */		   			0,
/* RES_FOOTER */		   			0,
/* RES_PRINT */						0,
/* RES_OPAQUE */					0,
/* RES_PROTECT */					0,
/* RES_SURROUND */					0,
/* RES_VERT_ORIENT */				0,
/* RES_HORI_ORIENT */				0,
/* RES_ANCHOR */					0,
/* RES_BACKGROUND */				0,
/* RES_BOX	*/                      0,
/* RES_SHADOW */					0,
/* RES_FRMMACRO */					0,
/* RES_COL */						0,
/* RES_KEEP */						0,
/* RES_URL */        	    		0,
/* RES_EDIT_IN_READONLY */        	0,
/* RES_LAYOUT_SPLIT */ 	    		0,
/* RES_FRMATR_DUMMY1 */        	    0, // Dummy:
/* RES_FRMATR_DUMMY2 */        	    0, // Dummy:
/* RES_AUTO_STYLE */        	    0, // Dummy:
/* RES_FRMATR_DUMMY4 */        	    0, // Dummy:
/* RES_FRMATR_DUMMY5 */        	    0, // Dummy:
/* RES_FRMATR_DUMMY6 */        	    0, // Dummy:
/* RES_FRMATR_DUMMY7 */        	    0, // Dummy:
/* RES_FRMATR_DUMMY8 */        	    0, // Dummy:
/* RES_FRMATR_DUMMY9 */        	    0, // Dummy:
/* RES_FOLLOW_TEXT_FLOW */          0,
/* RES_WRAP_INFLUENCE_ON_OBJPOS */  0,
/* RES_FRMATR_DUMMY2 */             0, // Dummy:
/* RES_AUTO_STYLE */                0, // Dummy:
/* RES_FRMATR_DUMMY4 */             0, // Dummy:
/* RES_FRMATR_DUMMY5 */             0, // Dummy:

/* RES_GRFATR_MIRRORGRF	*/			0,
/* RES_GRFATR_CROPGRF	*/			0,
/* RES_GRFATR_ROTATION */			0,
/* RES_GRFATR_LUMINANCE */			0,
/* RES_GRFATR_CONTRAST */			0,
/* RES_GRFATR_CHANNELR */			0,
/* RES_GRFATR_CHANNELG */			0,
/* RES_GRFATR_CHANNELB */			0,
/* RES_GRFATR_GAMMA */				0,
/* RES_GRFATR_INVERT */				0,
/* RES_GRFATR_TRANSPARENCY */		0,
/* RES_GRFATR_DRWAMODE */			0,
/* RES_GRFATR_DUMMY1 */				0,
/* RES_GRFATR_DUMMY2 */				0,
/* RES_GRFATR_DUMMY3 */				0,
/* RES_GRFATR_DUMMY4 */				0,
/* RES_GRFATR_DUMMY5 */				0,

/* RES_BOXATR_FORMAT */				0,
/* RES_BOXATR_FORMULA */			0,
/* RES_BOXATR_VALUE */				0
};
