Pascal Sancho <pascal.sancho <at> takoma.fr> writes: > > Hi Santanu, > > on this list we start with XSL-FO as input, so you should explain what > do you expect precisely as output rendering, what do you get, and > provide a short XSL-FO snippet as material if taht can help (see [1]). > > Your question may also concern: > - XSLT > - understanding XSL-FO > - etc. > > You can get further info on [Other Resources] page at [2] > > [1] http://xmlgraphics.apache.org/fop/maillist.html#fop-user-policy > [2] http://xmlgraphics.apache.org/fop/resources.html > > Le 17/01/2012 14:19, Santanu Dutta a écrit : > > > > Hi: > > > > I'm creating PDF files from input XML, everything works fine except some table- > > cells, having rowsep and colsep. It looks some separator lines are just doubled. > > > > I am new to XSL-FO and require your help. Is there anyone to help me, please! > > > > Santanu >
Hi: Thanks Luis and Pascal, for your prompt reply. Here is my transform file: ---------------- <?xml version="1.0" encoding="utf-8"?> <xsl:transform xmlns="http://www.w3.org/1999/xhtml" xmlns:cals="http://www.oasis-open.org/specs/tm9901" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="cals" version="2.0"> <!-- Process CALS tables, using code borrowed from Andrew Welch http://www.biglist.com/lists/xsl-list/archives/200202/msg00666.html--> <xsl:template match="tgroup"> <xsl:comment> <xsl:value-of select="@cols"/> </xsl:comment> <fo:table table-layout="fixed" border-collapse="collapse" > <!-- border="1pt solid black" --> <xsl:if test="@align"> <xsl:attribute name="text-align"> <xsl:value-of select="@align"/> </xsl:attribute> </xsl:if> <xsl:choose> <xsl:when test="../@frame='topbot'"> <xsl:attribute name="style">border-top:.5pt solid black;border-bottom:.5pt solid black</xsl:attribute> </xsl:when> <xsl:when test="../@frame='all'"> <xsl:attribute name="border">.5pt solid black</xsl:attribute> </xsl:when> <xsl:otherwise> <xsl:attribute name="border">0</xsl:attribute> </xsl:otherwise> </xsl:choose> <xsl:variable name="colgroup"> <!-- <fo:table-column><xsl:comment>colgroup</xsl:comment> --> <xsl:call-template name="generate.colgroup"> <xsl:with-param name="cols" select="count(colspec)"/> </xsl:call-template> <!-- </fo:table-column> --> </xsl:variable> <xsl:copy-of select="$colgroup"/> <xsl:apply-templates/> </fo:table> </xsl:template> <xsl:template match="colspec"/> <xsl:template match="spanspec"/> <xsl:template match="thead|tfoot"> <xsl:element name="{name(.)}"> <xsl:if test="@align"> <xsl:attribute name="text-align"> <xsl:value-of select="@align"/> </xsl:attribute> </xsl:if> <xsl:if test="@char"> <xsl:attribute name="char"> <xsl:value-of select="@char"/> </xsl:attribute> </xsl:if> <xsl:if test="@charoff"> <xsl:attribute name="charoff"> <xsl:value-of select="@charoff"/> </xsl:attribute> </xsl:if> <xsl:if test="@valign"> <xsl:attribute name="display-align"> <xsl:choose> <xsl:when test="@valign = top">before</xsl:when> <xsl:when test="@valign = middle">center</xsl:when> <xsl:otherwise>auto</xsl:otherwise> </xsl:choose> </xsl:attribute> </xsl:if> <xsl:apply-templates/> </xsl:element> </xsl:template> <xsl:template match="tbody"> <fo:table-body> <xsl:if test="@align"> <xsl:attribute name="text-align"> <xsl:value-of select="@align"/> </xsl:attribute> </xsl:if> <xsl:if test="@char"> <xsl:attribute name="char"> <xsl:value-of select="@char"/> </xsl:attribute> </xsl:if> <xsl:if test="@charoff"> <xsl:attribute name="charoff"> <xsl:value-of select="@charoff"/> </xsl:attribute> </xsl:if> <xsl:if test="@valign"> <xsl:attribute name="display-align"> <xsl:choose> <xsl:when test="@valign = top">before</xsl:when> <xsl:when test="@valign = middle">center</xsl:when> <xsl:otherwise>auto</xsl:otherwise> </xsl:choose> </xsl:attribute> </xsl:if> <xsl:apply-templates/> </fo:table-body> </xsl:template> <xsl:template match="row"> <fo:table-row> <xsl:if test="@rowsep='1'"> <xsl:attribute name="border-bottom">.5pt solid black</xsl:attribute> </xsl:if> <xsl:if test="@rowsep='0'"> <xsl:attribute name="border-bottom">none</xsl:attribute> </xsl:if> <xsl:if test="@align"> <xsl:attribute name="text-align"> <xsl:value-of select="@align"/> </xsl:attribute> </xsl:if> <xsl:if test="@char"> <xsl:attribute name="char"> <xsl:value-of select="@char"/> </xsl:attribute> </xsl:if> <xsl:if test="@charoff"> <xsl:attribute name="charoff"> <xsl:value-of select="@charoff"/> </xsl:attribute> </xsl:if> <xsl:if test="@valign"> <xsl:attribute name="display-align"> <xsl:choose> <xsl:when test="@valign = top">before</xsl:when> <xsl:when test="@valign = middle">center</xsl:when> <xsl:otherwise>auto</xsl:otherwise> </xsl:choose> </xsl:attribute> </xsl:if> <xsl:apply-templates/> </fo:table-row> </xsl:template> <xsl:template match="entry/p"> <fo:block font-size="7pt" line-height="8pt" > <xsl:if test="../@align='center'"> <xsl:attribute name="text-align">center</xsl:attribute> </xsl:if> <xsl:if test="@align"> <xsl:attribute name="text-align"><xsl:value-of select="@align"/> </xsl:attribute> </xsl:if> <xsl:apply-templates/> </fo:block> </xsl:template> <xsl:template match="thead/row/entry"> <xsl:call-template name="process.cell"> <xsl:with-param name="cellgi">fo:table-cell</xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template match="tbody/row/entry"> <xsl:call-template name="process.cell"> <xsl:with-param name="cellgi">fo:table-cell</xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template match="tfoot/row/entry"> <xsl:call-template name="process.cell"> <xsl:with-param name="cellgi">fo:table-cell</xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template name="process.cell"> <xsl:param name="cellgi">fo:table-cell</xsl:param> <xsl:variable name="empty.cell" select="count(node()) = 0"/> <xsl:variable name="entry.colnum"> <xsl:call-template name="entry.colnum"/> </xsl:variable> <xsl:if test="$entry.colnum != ''"> <xsl:variable name="prev.entry" select="preceding-sibling::*[1]"/> <xsl:variable name="prev.ending.colnum"> <xsl:choose> <xsl:when test="$prev.entry"> <xsl:call-template name="entry.ending.colnum"> <xsl:with-param name="entry" select="$prev.entry"/> </xsl:call-template> </xsl:when> <xsl:otherwise>0</xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:call-template name="add-empty-entries"> <xsl:with-param name="number"> <xsl:choose> <xsl:when test="$prev.ending.colnum = ''">0</xsl:when> <xsl:otherwise> <xsl:value-of select="$entry.colnum - $prev.ending.colnum - 1"/> </xsl:otherwise> </xsl:choose> </xsl:with-param> </xsl:call-template> </xsl:if> <xsl:element name="{$cellgi}"> <xsl:attribute name="border-right">.25pt solid black</xsl:attribute> <xsl:attribute name="border-bottom">.25pt solid black</xsl:attribute> <xsl:attribute name="margin">0mm</xsl:attribute> <xsl:attribute name="padding">2pt</xsl:attribute> <xsl:attribute name="font-size">7pt</xsl:attribute> <xsl:attribute name="line-height">8pt</xsl:attribute> <!--<xsl:if test="ancestor-or-self::*/@rowsep ='0' "><xsl:attribute name="border-bottom">none</xsl:attribute></xsl:if> <xsl:if test="ancestor-or-self::*/@colsep ='0' "><xsl:attribute name="border-right">none</xsl:attribute></xsl:if>--> <xsl:if test="@class = 'thead'"> <xsl:attribute name="color"> black </xsl:attribute> <!-- <xsl:attribute name="border">.5pt solid black </xsl:attribute> --> </xsl:if> <xsl:if test="@align"> <xsl:attribute name="text-align"> <xsl:value-of select="@align"/> </xsl:attribute> </xsl:if> <xsl:if test="@spanname"> <xsl:variable name="spanname"> <xsl:value-of select="@spanname"/> </xsl:variable> <xsl:variable name="ancetre" select="ancestor::tgroup/spanspec[@spanname=$spanname]"/> <xsl:variable name="namest" select="$ancetre/@namest"/> <xsl:variable name="nameend" select="$ancetre/@nameend"/> <xsl:variable name="colst" select="ancestor::* [colspec/@colname=$namest]/colspec[@colname=$namest]/@colnum"/> <xsl:variable name="colend" select="ancestor::* [colspec/@colname=$nameend]/colspec[@colname=$nameend]/@colnum"/> <xsl:attribute name="number-columns-spanned"> <xsl:value-of select="number($colend) - number($colst) + 1"/> </xsl:attribute> <!-- <xsl:comment>spanname: <xsl:value-of select="@spanname"/> </xsl:comment> <xsl:comment>ancetre: <xsl:value-of select="$ancetre"/> </xsl:comment> <xsl:comment>namest: <xsl:value-of select="$namest"/> </xsl:comment> <xsl:comment>namend: <xsl:value-of select="$nameend"/> </xsl:comment> <xsl:comment>colst: <xsl:value-of select="$colst"/> </xsl:comment> <xsl:comment>colend: <xsl:value-of select="$colend"/> </xsl:comment> <xsl:comment>align: <xsl:value-of select="@align"/> </xsl:comment> --> </xsl:if> <xsl:if test="@morerows"> <xsl:attribute name="number-rows-spanned"> <xsl:value-of select="@morerows+1"/> </xsl:attribute> </xsl:if> <xsl:if test="@namest"> <xsl:attribute name="number-columns-spanned"> <xsl:call-template name="calculate.colspan"/> </xsl:attribute> </xsl:if> <xsl:if test="@char"> <xsl:attribute name="char"> <xsl:value-of select="@char"/> </xsl:attribute> </xsl:if> <xsl:if test="@charoff"> <xsl:attribute name="charoff"> <xsl:value-of select="@charoff"/> </xsl:attribute> </xsl:if> <xsl:if test="@valign"> <xsl:attribute name="display-align"> <xsl:choose> <xsl:when test="@valign = top">before</xsl:when> <xsl:when test="@valign = middle">center</xsl:when> <xsl:otherwise>auto</xsl:otherwise> </xsl:choose> </xsl:attribute> </xsl:if> <xsl:if test="@rowsep='1'"> <xsl:attribute name="border-bottom">.5pt solid black</xsl:attribute> </xsl:if> <xsl:if test="@rowsep='0'"> <xsl:attribute name="border-bottom">none</xsl:attribute> </xsl:if> <xsl:if test="@colsep='1'"> <xsl:attribute name="border-right">.5pt solid black</xsl:attribute> </xsl:if> <xsl:if test="@colsep='0'"> <xsl:attribute name="border-right">none</xsl:attribute> </xsl:if> <xsl:if test="not(preceding-sibling::*) and ancestor::row/@id"> <a name="{ancestor::row/@id}"/> </xsl:if> <xsl:if test="@id"> <a name="{@id}"/> </xsl:if> <xsl:choose> <xsl:when test="$empty.cell"> <fo:block> <xsl:text> </xsl:text> </fo:block> </xsl:when> <xsl:otherwise> <xsl:apply-templates/> </xsl:otherwise> </xsl:choose> </xsl:element> </xsl:template> <xsl:template name="add-empty-entries"> <xsl:param name="number" select="'0'"/> <xsl:choose> <xsl:when test="$number <= 0"/> <xsl:otherwise> <fo:table-cell> <!--<xsl:attribute name="border">.5pt solid red</xsl:attribute>--> <xsl:attribute name="padding">5pt</xsl:attribute> <fo:block/> </fo:table-cell> <xsl:call-template name="add-empty-entries"> <xsl:with-param name="number" select="$number - 1"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="entry.colnum"> <xsl:param name="entry" select="."/> <xsl:choose> <xsl:when test="$entry/@colname"> <xsl:variable name="colname" select="$entry/@colname"/> <xsl:variable name="colspec" select="$entry/ancestor::tgroup/colspec[@colname=$colname]"/> <xsl:call-template name="colspec.colnum"> <xsl:with-param name="colspec" select="$colspec"/> </xsl:call-template> </xsl:when> <xsl:when test="$entry/@namest"> <xsl:variable name="namest" select="$entry/@namest"/> <xsl:variable name="colspec" select="$entry/ancestor::tgroup/colspec[@colname=$namest]"/> <xsl:call-template name="colspec.colnum"> <xsl:with-param name="colspec" select="$colspec"/> </xsl:call-template> </xsl:when> <xsl:when test="count($entry/preceding-sibling::*) = 0">1</xsl:when> <xsl:otherwise> <xsl:variable name="pcol"> <xsl:call-template name="entry.ending.colnum"> <xsl:with-param name="entry" select="$entry/preceding- sibling::*[1]"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="$pcol + 1"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="entry.ending.colnum"> <xsl:param name="entry" select="."/> <xsl:choose> <xsl:when test="$entry/@colname"> <xsl:variable name="colname" select="$entry/@colname"/> <xsl:variable name="colspec" select="$entry/ancestor::tgroup/colspec[@colname=$colname]"/> <xsl:call-template name="colspec.colnum"> <xsl:with-param name="colspec" select="$colspec"/> </xsl:call-template> </xsl:when> <xsl:when test="$entry/@nameend"> <xsl:variable name="nameend" select="$entry/@nameend"/> <xsl:variable name="colspec" select="$entry/ancestor::tgroup/colspec[@colname=$nameend]"/> <xsl:call-template name="colspec.colnum"> <xsl:with-param name="colspec" select="$colspec"/> </xsl:call-template> </xsl:when> <xsl:when test="count($entry/preceding-sibling::*) = 0">1</xsl:when> <xsl:otherwise> <xsl:variable name="pcol"> <xsl:call-template name="entry.ending.colnum"> <xsl:with-param name="entry" select="$entry/preceding- sibling::*[1]"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="$pcol + 1"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="colspec.colnum"> <xsl:param name="colspec" select="."/> <xsl:choose> <xsl:when test="$colspec/@colnum"> <xsl:value-of select="$colspec/@colnum"/> </xsl:when> <xsl:when test="$colspec/preceding-sibling::colspec"> <xsl:variable name="prec.colspec.colnum"> <xsl:call-template name="colspec.colnum"> <xsl:with-param name="colspec" select="$colspec/preceding-sibling::colspec[1]"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="$prec.colspec.colnum + 1"/> </xsl:when> <xsl:otherwise>1</xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="generate.colgroup"> <xsl:param name="cols" select="1"/> <xsl:param name="count" select="1"/> <xsl:choose> <xsl:when test="$count>$cols"/> <xsl:otherwise> <xsl:call-template name="generate.col"> <xsl:with-param name="countcol" select="$count"/> </xsl:call-template> <xsl:call-template name="generate.colgroup"> <xsl:with-param name="cols" select="$cols"/> <xsl:with-param name="count" select="$count+1"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="generate.col"> <xsl:param name="countcol">1</xsl:param> <xsl:param name="colspecs" select="./colspec"/> <xsl:param name="count">1</xsl:param> <xsl:param name="colnum">1</xsl:param> <xsl:choose> <xsl:when test="$count>count($colspecs)"> <fo:table-column/> <xsl:comment>$colspecs</xsl:comment> </xsl:when> <xsl:otherwise> <xsl:variable name="colspec" select="$colspecs[$count=position()]"/> <xsl:variable name="colspec.colnum"> <xsl:choose> <xsl:when test="$colspec/@colnum"> <xsl:value-of select="$colspec/@colnum"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$colnum"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:choose> <xsl:when test="$colspec.colnum=$countcol"> <fo:table-column> <!-- <xsl:attribute name="column-width"><xsl:value-of select="$colspec/@colwidth"/></xsl:attribute> --> <xsl:attribute name="column-width"> <xsl:call-template name="calc.column.width"> <xsl:with-param name="colwidth"> <xsl:value-of select="$colspec/@colwidth"/> </xsl:with-param> </xsl:call-template> </xsl:attribute> <!--<xsl:comment>$countcol</xsl:comment>--> <xsl:if test="$colspec/@align"> <xsl:attribute name="text-align"> <xsl:value-of select="$colspec/@align"/> </xsl:attribute> </xsl:if> <xsl:if test="$colspec/@char"> <xsl:attribute name="char"> <xsl:value-of select="$colspec/@char"/> </xsl:attribute> </xsl:if> <xsl:if test="$colspec/@charoff"> <xsl:attribute name="charoff"> <xsl:value-of select="$colspec/@charoff"/> </xsl:attribute> </xsl:if> </fo:table-column> </xsl:when> <xsl:otherwise> <xsl:call-template name="generate.col"> <xsl:with-param name="countcol" select="$countcol"/> <xsl:with-param name="colspecs" select="$colspecs"/> <xsl:with-param name="count" select="$count+1"/> <xsl:with-param name="colnum"> <xsl:choose> <xsl:when test="$colspec/@colnum"> <xsl:value-of select="$colspec/@colnum + 1"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$colnum + 1"/> </xsl:otherwise> </xsl:choose> </xsl:with-param> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="colspec.colwidth"> <!-- when this macro is called, the current context must be an entry --> <xsl:param name="colname"/> <!-- .. = row, ../.. = thead|fo:table-body, ../../.. = tgroup --> <xsl:param name="colspecs" select="../../../../tgroup/colspec"/> <xsl:param name="count">1</xsl:param> <xsl:choose> <xsl:when test="$count>count($colspecs)"/> <xsl:otherwise> <xsl:variable name="colspec" select="$colspecs[$count=position()]"/> <xsl:choose> <xsl:when test="$colspec/@colname=$colname"> <xsl:value-of select="$colspec/@colwidth"/> </xsl:when> <xsl:otherwise> <xsl:call-template name="colspec.colwidth"> <xsl:with-param name="colname" select="$colname"/> <xsl:with-param name="colspecs" select="$colspecs"/> <xsl:with-param name="count" select="$count+1"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="calculate.colspan"> <xsl:param name="entry" select="."/> <xsl:variable name="namest" select="$entry/@namest"/> <xsl:variable name="nameend" select="$entry/@nameend"/> <xsl:variable name="scol"> <xsl:call-template name="colspec.colnum"> <xsl:with-param name="colspec" select="$entry/ancestor::tgroup/colspec[@colname=$namest]"/> </xsl:call-template> </xsl:variable> <xsl:variable name="ecol"> <xsl:call-template name="colspec.colnum"> <xsl:with-param name="colspec" select="$entry/ancestor::tgroup/colspec[@colname=$nameend]"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="$ecol - $scol + 1"/> </xsl:template> <xsl:template name="calc.column.width"> <!-- ** * <p>Calculate an XSL FO table column-width specification from a * full relative table column-width specification.</p> * * <p>Table column-widths are in the following basic * forms:</p> * * <ul> * <li><b>99.99units</b>, a fixed length-specifier.</li> * <li><b>99.99</b>, a fixed length-specifier without any units.</li> * <li><b>99.99*</b>, a relative length-specifier.</li> * <li><b>99.99*+99.99units</b>, a combination of both.</li> * </ul> * * <p>The units are points (pt), picas (pi), centimeters (cm), * millimeters (mm), and inches (in). These are the same units as XSL, * except that XSL abbreviates picas "pc" instead of "pi". If a length * specifier has no units, the default unit (pt) is assumed.</p> * * <p>Relative length-specifiers are represented in XSL with the * proportional-column-width() function.</p> * * <p>Here are some examples:</p> * * <ul> * <li>"36pt" becomes "36pt"</li> * <li>"3pi" becomes "3pc"</li> * <li>"36" becomes "36pt"</li> * <li>"3*" becomes "proportional-column-width(3)"</li> * <li>"3*+2pi" becomes "proportional-column-width(3)+2pc"</li> * <li>"1*+2" becomes "proportional-column-width(1)+2pt"</li> * </ul> * * @param colwidth The column width specification. * * @returns The XSL column width specification. * --> <xsl:param name="colwidth">1*</xsl:param> <!-- Ok, the colwidth could have any one of the following forms: --> <!-- 1* = proportional width --> <!-- 1unit = 1.0 units wide --> <!-- 1 = 1pt wide --> <!-- 1*+1unit = proportional width + some fixed width --> <!-- 1*+1 = proportional width + some fixed width --> <!-- If it has a proportional width, translate it to XSL --> <xsl:if test="contains($colwidth, '*')"> <xsl:text>proportional-column-width(</xsl:text> <xsl:value-of select="substring-before($colwidth, '*')"/> <xsl:text>)</xsl:text> </xsl:if> <!-- Now get the non-proportional part of the specification --> <xsl:variable name="width-units"> <xsl:choose> <xsl:when test="contains($colwidth, '*')"> <xsl:value-of select="normalize-space(substring- after($colwidth, '*'))"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="normalize-space($colwidth)"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <!-- Now the width-units could have any one of the following forms: --> <!-- = <empty string> --> <!-- 1unit = 1.0 units wide --> <!-- 1 = 1pt wide --> <!-- with an optional leading sign --> <!-- Get the width part by blanking out the units part and discarding -- > <!-- white space. --> <xsl:variable name="width" select="normalize-space(translate($width- units, '+-0123456789.abcdefghijklmnopqrstuvwxyz', '+-0123456789.'))"/> <!-- Get the units part by blanking out the width part and discarding -- > <!-- white space. --> <xsl:variable name="units" select="normalize-space(translate($width- units, 'abcdefghijklmnopqrstuvwxyz+-0123456789.', 'abcdefghijklmnopqrstuvwxyz'))"/> <!-- Output the width --> <xsl:value-of select="$width"/> <!-- Output the units, translated appropriately --> <xsl:choose> <xsl:when test="$units = 'pi'">pc</xsl:when> <xsl:when test="$units = '' and $width != ''">pt</xsl:when> <xsl:otherwise> <xsl:value-of select="$units"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:transform> ---------------- My problem lies within line# 193 to 197 (look for <!--problem-block ***-->). With this stylesheet everything works fine, except for colsep border. Viewing PDF in Acrobat /Foxit Reader(in any zooming ratio) shows some doubled column separators. I'm using fop 0.95 and oXygen editor for the transformation process. Looking forward to your reply. Thanks again. Regards, Santanu --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
