[xep-support] Re: CoolTool - Line Numbering version 2

Kevin Brown kevin at renderx.com
Thu Aug 28 14:23:02 PDT 2014


OK, we had a few inquiries already so I modified the latest CoolTool for
line numbering. 

1) Accessibility

If you had Accessibility turned on and ran the XSL, the resulting XEP file
would fail to format by RenderX. This is because the RenderX PDF producer
when in Accessibility mode is expecting some Xpath expression on every text
element. Accessibility (aka tagged PDF or Section 508 compliant PDF) does
many things, one of which is to build a complete Xpath of all parts of a
document inside the PDF so it can be navigated and read out loud. 

So the new XSL below has a param which you would set to enable this in the
output. It just copies the Xpath of the element it is on. This is acceptable
since I also mark the line number as a "PDF Artifact" which means it would
be disregarded by screen readers and such. 

Note: I implemented this feature before and forgot, we have legislative
customers that actually want the line numbers in the content and read out
loud using alternative text. Thus, you can get screen readers to read the
resulting PDF like this:

"Line number 1. The State of California hereby declares"
"Line number 2. that the following resolutions shall be regarded"
... 

2) Font for line numbers

Another person requested the ability to specify the font for the line
numbers and not use the font that is on the line in question. The XSL has
that changed inserted (you can certainly change or remove if you like). 

There is a variable at the top in which you can set the font size ("fsize").
It takes RenderX units which are 1/100 of a pt. This XSL defaults to 9000 or
9pts. Just like with the color, you would put down the color you want for
the text of the line number and now the font, then after you put down the
line number you restore the previous color and font. 
You can certainly remove either or both the color and font.

Kevin Brown
RenderX

**** Changed XSL ****

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xep="http://www.renderx.com/XEP/xep"
    version="2.0">
    <!--true() for Accessible documents, 
        false() if you are not producing Accessible documents -->
    <xsl:param name="access" select="true()"/>
    <xsl:variable name="xpos" select="10000"/>
    <xsl:variable name="tolerance" select="1000"/>
    <xsl:variable name="numcolor" select=".2"/>
    <xsl:variable name="fsize" select="9000"/>

    <xsl:template match="xep:text">
        <xsl:variable name="ypos" select="@y"/>
        <xsl:variable name="test1"
select="preceding-sibling::xep:text[not(@y=$ypos)]"/>
        <xsl:variable name="test2" select="distinct-values($test1/@y)"/>
        <xsl:variable name="linenum" select="count($test2) + 1"/>
        <xsl:variable name="numbering"
select="string(preceding-sibling::xep:pinpoint[1]/@value)"/>
        <!-- if the "Y" is unique, put down a linenumber -->
        <xsl:if test="not(preceding-sibling::xep:text/@y = $ypos) and
($numbering='' or $numbering='numbered')">
            <xep:gray-color gray="{$numcolor}"/>
            <xep:font family="Helvetica" weight="400" style="normal"
variant="normal" size="{$fsize}"/>
            <xep:text x="{$xpos}" y="{$ypos}" value="{$linenum}"
width="7000">
                <!-- Add accessibility attribute, mark as Artifact -->
                <xsl:if test="$access">
                    <xsl:attribute name="xpath">
                        <xsl:value-of select="@xpath"/>
                    </xsl:attribute>
                    <xsl:attribute name="pdf-structure-tag">
                        <xsl:text>Artifact</xsl:text>
                    </xsl:attribute>
                </xsl:if>
            </xep:text>
            <xsl:copy-of select="preceding-sibling::*[contains(name(),
'font')]"/>
            <xsl:copy-of select="preceding-sibling::*[contains(name(),
'color')]"/>
            
        </xsl:if>
        <xsl:copy-of select="."/>
    </xsl:template>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>



-----Original Message-----
From: Kevin Brown [mailto:kevin at renderx.com] 
Sent: Wednesday, August 27, 2014 11:30 AM
To: kevin at renderx.com; 'RenderX Community Support List'
Subject: RE: [xep-support] CoolTool - Line Numbering

And attached is a sample output. As you can see at the very end, the issue
would exist with the last row of the table where it numbers 29-27-28. This
is because the last cell in that row is done first (yielding 27 and 28) then
the next cell with "higher" content is encountered (29). You would have this
limitation if you bottom align things and they vary in height.

Note: This also shows that the font-size of the number picks up from the
content encountered. You could certainly modify that behavior also in the
style sheet and use a fixed font size. You would need to implement this just
like the color, getting the previous value and outputting that back after
you put down the line number. 

Kevin

-----Original Message-----
From: Xep-support [mailto:xep-support-bounces at renderx.com] On Behalf Of
Kevin Brown
Sent: Wednesday, August 27, 2014 11:18 AM
To: 'RenderX Community Support List'
Subject: [xep-support] CoolTool - Line Numbering

As I posted before, RenderX has an extension called "rx:ruler" that can be
used to lay down numbers on a page. This is not a true "line numberer", it
is a measuring stick. It was created for a very specific application
(legislation) and met the requirements of the customer. It was included into
XEP then and never documented, but it is there for all to use.

On another project, I developed an identity XSL that can be applied to the
RenderX Intermediate Format (XEPOUT) to understand lines of text and create
a numbering system. In XEPOUT, all text is represented by the <xep:text>
element. An <xep:text> element will also carry information on its position
(i.e. the "y" position on the page). A very simple 2.0 XSL can be used to go
through the document and inject line numbers at a specified location when an
<xep:text> element whose "y" is different from than last one. It is
important to have the "y" is different because you may have phrases on the
same line in different <xep:text> elements especially in the case of
kerning.

There are a few limitations in this method, specifically in the area of
tables. Tables in XEP rendered into XEPOUT do not necessarily follow
document order. You could design a table cell with say the cell contents
aligned to the bottom and have differing numbers of lines of text in the
cell. XEP outputs tables right to left, top to bottom and something like
this would get numbered incorrectly (the "Col" in "Col 3" would come before
the "Big" in "Big Col 2" in the XEPOUT.

       Big
Col    Col	 Col
 1      2     3

The variable "xpos" is the X position where you want to line numbers. 
I also had added a tolerance variable but did not have to implement it. You
certainly could do so. You would likely need it if you have
superscript/subscript.
The variable "numcolor" is a gray color value, you could of course do
something different.

This solution also makes use of adding <xep:pinpoint> elements into the
document to mark areas where you do not want to number. I used this for
excluding header/footer areas. One would do something like this in the
static-content areas. The pinpoints will be dropped into the XEPOUT to mark
the area where you do not want numbers, 

<fo:static-content flow-name="xsl-region-before">
         <fo:block><rx:pinpoint value="notnumbered"/></fo:block>
         <fo:list-block font="10pt Helvetica"
provisional-distance-between-starts="5in"
provisional-label-separation="0in">
            <fo:list-item>
               <fo:list-item-label end-indent="label-end()">
                  <fo:block text-align="start" font-weight="bold">   Block
Properties - Borders  </fo:block>
               </fo:list-item-label>
               <fo:list-item-body start-indent="body-start()">
                  <fo:block text-align="end">
                     Page <fo:page-number/>
                  </fo:block>
               </fo:list-item-body>
            </fo:list-item>
         </fo:list-block>
         <fo:block><rx:pinpoint value="numbered"/></fo:block>
      </fo:static-content>


Anyway, here is the sample XSL free for all to use and modify. If you find
it useful, great. Make any modifications and please post it back for all.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xep="http://www.renderx.com/XEP/xep"
    version="2.0">
    <xsl:variable name="xpos" select="10000"/>
    <xsl:variable name="tolerance" select="1000"/>
    <xsl:variable name="numcolor" select=".2"/>

    <xsl:template match="xep:text">
        <xsl:variable name="ypos" select="@y"/>
        <xsl:variable name="test1"
select="preceding-sibling::xep:text[not(@y=$ypos)]"/>
        <xsl:variable name="test2" select="distinct-values($test1/@y)"/>
        <xsl:variable name="linenum" select="count($test2) + 1"/>
        <xsl:variable name="numbering"
select="string(preceding-sibling::xep:pinpoint[1]/@value)"/>
        <!-- if the "Y" is unique, put down a linenumber -->
        <xsl:if test="not(preceding-sibling::xep:text/@y = $ypos) and
($numbering='' or $numbering='numbered')">
            <xep:gray-color gray="{$numcolor}"/>
            <xep:text x="{$xpos}" y="{$ypos}" value="{$linenum}"
width="7000"/>
            <xsl:copy-of select="preceding-sibling::*[contains(name(),
'color')]"/>
        </xsl:if>
        <xsl:copy-of select="."/>
    </xsl:template>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

_______________________________________________
(*) To unsubscribe, please visit
http://lists.renderx.com/mailman/options/xep-support
(*) By using the Service, you expressly agree to these Terms of Service
http://w ww.renderx.com/terms-of-service.html



More information about the Xep-support mailing list