sw/source/filter/html/css1atr.cxx | 52 ++++++++++++++++++++++++++++++++++++- sw/source/filter/html/css1kywd.cxx | 1 sw/source/filter/html/css1kywd.hxx | 1 sw/source/filter/html/htmlatr.cxx | 23 ++++++++++++++++ sw/source/filter/html/wrthtml.cxx | 22 +++++++++++++++ sw/source/filter/html/wrthtml.hxx | 7 ++++ 6 files changed, 104 insertions(+), 2 deletions(-)
New commits: commit c074df40639593f73993e36be08aa8c685b55b55 Author: László Németh <nem...@collabora.com> Date: Tue Dec 16 01:34:38 2014 +0100 HTML export: optional CSS2 dot leaders in the Table of Contents To use it, enable "Print layout" in Options->Load/Save->HTML Compatibility, and select the HTML Document file type in the Writer Save As dialog. Change-Id: I763ab8340a59050fd5c68677715679f41fd91fb3 diff --git a/sw/source/filter/html/css1atr.cxx b/sw/source/filter/html/css1atr.cxx index 049fdb17..b059fea 100644 --- a/sw/source/filter/html/css1atr.cxx +++ b/sw/source/filter/html/css1atr.cxx @@ -112,6 +112,8 @@ using editeng::SvxBorderLine; #define CSS1_FRMSIZE_ANYHEIGHT 0x0e #define CSS1_FRMSIZE_PIXEL 0x10 +#define DOT_LEADERS_MAX_WIDTH 18 + extern SwAttrFnTab aCSS1AttrFnTab; static Writer& OutCSS1_SwFmt( Writer& rWrt, const SwFmt& rFmt, @@ -220,6 +222,48 @@ void SwHTMLWriter::OutCSS1_Property( const sal_Char *pProp, OutNewLine(); sOut.append("<" + OString(OOO_STRING_SVTOOLS_HTML_style) + " " + OString(OOO_STRING_SVTOOLS_HTML_O_type) + "=\"text/css\">"); + // Optional CSS2 code for dot leaders (dotted line between the Table of Contents titles and page numbers): + // (More inforation: http://www.w3.org/Style/Examples/007/leaders.en.html) + // + // p.leaders { + // /* FIXME: + // (1) dots line up vertically only in the paragraphs with the same alignation/level + // (2) max-width = 18 cm instead of 80em; possible improvement with the new CSS3 calc() */ + // max-width: 18cm; /* note: need to overwrite max-width with max-width - border-left_of_the_actual_paragraph */ + // padding: 0; + // overflow-x: hidden; + // line-height: 120%; /* note: avoid HTML scrollbars and missing descenders of the letters */ + // } + // p.leaders:after { + // float: left; + // width: 0; + // white-space: nowrap; + // content: ". . . . . . . . . . . . . . . . . . ..."; + // } + // p.leaders span:first-child { + // padding-right: 0.33em; + // background: white; + // } + // p.leaders span + span { + // float: right; + // padding-left: 0.33em; + // background: white; + // position: relative; + // z-index: 1 + // } + + if (bCfgPrintLayout) { + sOut.append( + "p." + OString(sCSS2_P_CLASS_leaders) + "{max-width:" + OString::number(DOT_LEADERS_MAX_WIDTH) + + "cm;padding:0;overflow-x:hidden;line-height:120%}" + + "p." + OString(sCSS2_P_CLASS_leaders) + ":after{float:left;width:0;white-space:nowrap;content:\""); + for (int i = 0; i < 100; i++ ) + sOut.append(". "); + sOut.append( + "\"}p." + OString(sCSS2_P_CLASS_leaders) + " span:first-child{padding-right:0.33em;background:white}" + + "p." + OString(sCSS2_P_CLASS_leaders) + " span+span{float:right;padding-left:0.33em;" + + "background:white;position:relative;z-index:1}"); + } Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); IncIndentLevel(); @@ -2739,7 +2783,8 @@ static Writer& OutCSS1_SvxLineSpacing( Writer& rWrt, const SfxPoolItem& rHt ) if( nHeight ) rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_line_height, (long)nHeight ); - else if( nPrcHeight ) + else if( nPrcHeight && + !(nPrcHeight < 115 && rHTMLWrt.bParaDotLeaders )) // avoid HTML scrollbars and missing descenders { OString sHeight(OString::number(nPrcHeight) + "%"); rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_line_height, sHeight); @@ -2954,6 +2999,11 @@ static Writer& OutCSS1_SvxLRSpace( Writer& rWrt, const SfxPoolItem& rHt ) if( rHTMLWrt.nDfltLeftMargin != nLeftMargin ) { rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_left, nLeftMargin ); + + // max-width = max-width - margin-left for TOC paragraphs with dot leaders + if( rHTMLWrt.bParaDotLeaders ) + rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_max_width, (long)(DOT_LEADERS_MAX_WIDTH/2.54*72*20) - nLeftMargin ); + } if( rHTMLWrt.nDfltRightMargin != rLRItem.GetRight() ) diff --git a/sw/source/filter/html/css1kywd.cxx b/sw/source/filter/html/css1kywd.cxx index da15ac9..6088d42 100644 --- a/sw/source/filter/html/css1kywd.cxx +++ b/sw/source/filter/html/css1kywd.cxx @@ -189,6 +189,7 @@ const sal_Char* sCSS1_PV_inset = "inset"; const sal_Char* sCSS1_PV_outset = "outset"; const sal_Char* sCSS1_P_width = "width"; +const sal_Char* sCSS1_P_max_width = "max-width"; const sal_Char* sCSS1_P_height = "height"; diff --git a/sw/source/filter/html/css1kywd.hxx b/sw/source/filter/html/css1kywd.hxx index 38a96fc..9522cd7 100644 --- a/sw/source/filter/html/css1kywd.hxx +++ b/sw/source/filter/html/css1kywd.hxx @@ -191,6 +191,7 @@ extern const sal_Char* sCSS1_PV_inset; extern const sal_Char* sCSS1_PV_outset; extern const sal_Char* sCSS1_P_width; +extern const sal_Char* sCSS1_P_max_width; extern const sal_Char* sCSS1_P_height; diff --git a/sw/source/filter/html/htmlatr.cxx b/sw/source/filter/html/htmlatr.cxx index c011dc1..beeba9d 100644 --- a/sw/source/filter/html/htmlatr.cxx +++ b/sw/source/filter/html/htmlatr.cxx @@ -946,12 +946,23 @@ void OutHTML_SwFmt( Writer& rWrt, const SwFmt& rFmt, if( !rHWrt.bNoAlign && pAdjItem ) OutHTML_SvxAdjust( rWrt, *pAdjItem ); + rHWrt.bParaDotLeaders = bPara && rHWrt.bCfgPrintLayout && rHWrt.indexOfDotLeaders( + pTxtNd->GetAnyFmtColl().GetPoolFmtId(), pTxtNd->GetTxt()) > -1; + // und nun ggf. noch die STYLE-Option if( rHWrt.bCfgOutStyles && rInfo.pItemSet && !bNoStyle) { OutCSS1_ParaTagStyleOpt( rWrt, *rInfo.pItemSet ); } + if (rHWrt.bParaDotLeaders) { + sOut += " " + OString(OOO_STRING_SVTOOLS_HTML_O_class) + "=\"" + + OString(sCSS2_P_CLASS_leaders) + "\"><" + + OString(OOO_STRING_SVTOOLS_HTML_O_span); + rWrt.Strm().WriteOString( sOut ); + sOut = ""; + } + rWrt.Strm().WriteChar( '>' ); // Soll ein </P> geschrieben wenrden @@ -2298,6 +2309,12 @@ Writer& OutHTML_SwTxtNode( Writer& rWrt, const SwCntntNode& rNode ) aFullText += aFootEndNoteSym; } + // Table of Contents or other paragraph with dot leaders? + sal_Int32 nIndexTab = rHTMLWrt.indexOfDotLeaders( nPoolId, rStr ); + if (nIndexTab > -1) + // skip part after the tabulator (page number) + nEnd = nIndexTab; + // gibt es harte Attribute, die als Tags geschrieben werden muessen? aFullText += rStr; HTMLEndPosLst aEndPosLst( rWrt.pDoc, rHTMLWrt.pTemplate, @@ -2628,6 +2645,12 @@ Writer& OutHTML_SwTxtNode( Writer& rWrt, const SwCntntNode& rNode ) nEnd > 0 && ' ' == rStr[nEnd-1] ) rHTMLWrt.bLFPossible = true; + // dot leaders: print the skipped page number in a different span element + if (nIndexTab > -1) { + OString sOut = OUStringToOString(rStr.copy(nIndexTab + 1), RTL_TEXTENCODING_ASCII_US); + rWrt.Strm().WriteOString( "</span><span>" + sOut + "</span>" ); + } + rHTMLWrt.bTagOn = false; OutHTML_SwFmtOff( rWrt, aFmtInfo ); diff --git a/sw/source/filter/html/wrthtml.cxx b/sw/source/filter/html/wrthtml.cxx index b28ce9f..28049c2 100644 --- a/sw/source/filter/html/wrthtml.cxx +++ b/sw/source/filter/html/wrthtml.cxx @@ -153,6 +153,8 @@ SwHTMLWriter::SwHTMLWriter( const OUString& rBaseURL ) , bCfgNetscape4( false ) , mbSkipImages(false) , mbSkipHeaderFooter(false) + , bCfgPrintLayout( false ) + , bParaDotLeaders( false ) { SetBaseURL(rBaseURL); } @@ -254,6 +256,8 @@ sal_uLong SwHTMLWriter::WriteStream() bCfgFormFeed = !IsHTMLMode(HTMLMODE_PRINT_EXT); bCfgCpyLinkedGrfs = rHtmlOptions.IsSaveGraphicsLocal(); + bCfgPrintLayout = rHtmlOptions.IsPrintLayoutExtension(); + // die HTML-Vorlage holen bool bOldHTMLMode = false; sal_uInt16 nOldTxtFmtCollCnt = 0, nOldCharFmtCnt = 0; @@ -1372,6 +1376,24 @@ sal_uInt16 SwHTMLWriter::GetHTMLFontSize( sal_uInt32 nHeight ) const return nSize; } +// Paragraphs with Table of Contents and other index styles will be typeset with +// dot leaders at the position of the last tabulator in PrintLayout (CSS2) mode +sal_Int32 SwHTMLWriter::indexOfDotLeaders( sal_uInt16 nPoolId, const OUString& rStr ) +{ + if (bCfgPrintLayout && ((nPoolId >= RES_POOLCOLL_TOX_CNTNT1 && nPoolId <= RES_POOLCOLL_TOX_CNTNT5) || + (nPoolId >= RES_POOLCOLL_TOX_IDX1 && nPoolId <= RES_POOLCOLL_TOX_IDX3) || + (nPoolId >= RES_POOLCOLL_TOX_USER1 && nPoolId <= RES_POOLCOLL_TOX_CNTNT10) || + nPoolId == RES_POOLCOLL_TOX_ILLUS1 || nPoolId == RES_POOLCOLL_TOX_TABLES1 || + nPoolId == RES_POOLCOLL_TOX_OBJECT1 || + (nPoolId >= RES_POOLCOLL_TOX_AUTHORITIES1 && nPoolId <= RES_POOLCOLL_TOX_USER10))) { + sal_Int32 i = rStr.lastIndexOf('\t'); + // there are only ASCII (Latin-1) characters after the tabulator + if (i > -1 && OUStringToOString(rStr.copy(i + 1), RTL_TEXTENCODING_ASCII_US).indexOf('?') == -1) + return i; + } + return -1; +} + // Struktur speichert die aktuellen Daten des Writers zwischen, um // einen anderen Dokument-Teil auszugeben, wie z.B. Header/Footer HTMLSaveData::HTMLSaveData(SwHTMLWriter& rWriter, sal_uLong nStt, diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx index 7cef620..8b3a6a2 100644 --- a/sw/source/filter/html/wrthtml.hxx +++ b/sw/source/filter/html/wrthtml.hxx @@ -402,7 +402,10 @@ public: /// If HTML header and footer should be written as well, or just the content itself. bool mbSkipHeaderFooter : 1; - // 23 +#define sCSS2_P_CLASS_leaders "leaders" + bool bCfgPrintLayout : 1; // PrintLayout option for TOC dot leaders + bool bParaDotLeaders : 1; // for TOC dot leaders + // 25 SwHTMLWriter( const OUString& rBaseURL ); virtual ~SwHTMLWriter(); @@ -576,6 +579,8 @@ public: static sal_uInt16 GetLangWhichIdFromScript( sal_uInt16 nScript ); FieldUnit GetCSS1Unit() const { return eCSS1Unit; } + + sal_Int32 indexOfDotLeaders( sal_uInt16 nPoolId, const OUString& rTxt ); }; inline bool SwHTMLWriter::IsCSS1Source( sal_uInt16 n ) const
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits