[Libreoffice-commits] core.git: Branch 'libreoffice-4-4' - sw/source
László Németh
nemeth at collabora.com
Mon Dec 15 16:48:16 PST 2014
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 <nemeth at 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
More information about the Libreoffice-commits
mailing list