Kaydet (Commit) 3e17677f authored tarafından László Németh's avatar László Németh

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
üst 758755e3
......@@ -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() )
......
......@@ -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";
......
......@@ -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;
......
......@@ -948,12 +948,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
......@@ -2300,6 +2311,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,
......@@ -2630,6 +2647,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 );
......
......@@ -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,
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment