Pages: 1
Print
Author Topic: Wrapping in Tables  (Read 6391 times)
mmoulder
Member

Posts: 43


« on: October 26, 2011, 11:40:14 AM »

When we generate a PDF document using Xmetal 6.0, if we have a long element such as a link, the text does not wrap within the table. This causes the text to write over itself. Is there a way to make this text wrap automatically is it exceeds the with of the column?
Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #1 on: October 26, 2011, 12:49:34 PM »

By default the output is designed to shrink the word and letter spacing so that a sentence or word fits on a line. In this case as your URL is considered a "word" (no spaces) it cannot be broken to line wrap and the entire thing is gets negative "kerning" applied to the point where in some cases letter may overlap making it unreadable.

There will be many different solutions for this, but one that I have decided seems to be best is to insert a ZERO WIDTH SPACE (U+200B) after certain characters within certain elements. This gives RenderX XEP the opportunity to break on these characters when necessary (and that take precedence over its text shrinking logic).

In your specific case you can try something like the following. In this case I had a client that often had very long URLs included with other code inside <codeph> so I was able to modify that specific template. If your long URLs are in some other element(s) then you will need to modify that/those instead. I'm not sure how easy it would be to make this universal but that might be worth looking into as well. Note that the other trick to this is that I always replace the specific character "/".

The following code change will work under these conditions:

1. You generate output using the deliverable named "XMetaL Enhanced PDF via RenderX XEP".
2. Your URL (or whatever your long text string is) contains the character "/" at regular intervals, with each chunk divided by it being short enough to fit within the containing space. This is easily modified if you want to break at other characters instead (see code).
3. Your URL is contained within the element <codeph>. This is easily modified but you will need the name of the template used for your element. A cross file text search tool (I use Notepad++ to write my XSLT). You may need to make modifications to more than one template in some cases.

File to change:
   %appdata%\SoftQuad\XMetaL Shared\DITA_OT\demo\xmfo\Customization\fo\xsl\custom.xsl

If you will be distributing this to other users it would be best to modify the following file instead and then redeploy the DITA OT:
   C:\Program Files\Common Files\XMetaL Shared\DITA_OT\demo\xmfo\Customization\fo\xsl\custom.xsl

Code:
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fo="http://www.w3.org/1999/XSL/Format"
    xmlns:exsl="http://exslt.org/common"
    xmlns:opentopic="http://www.idiominc.com/opentopic"
    xmlns:exslf="http://exslt.org/functions"
    xmlns:opentopic-func="http://www.idiominc.com/opentopic/exsl/function"
    extension-element-prefixes="exsl"
    exclude-result-prefixes="opentopic exslf opentopic-func"
    version="1.1">

    <!--
        
        ****************************************
        Template customization driver file
        v 0.91
        August 8, 2007
        ****************************************
        
        This driver file:
        1. collects the XSL template overrides via xsl:import
        2. sets header and footer content overrides
        (to style headers and footers, see [Customization]/fo/attrs/custom.xsl)
    -->

    <xsl:import href="xm_image_size_fix.xsl"/>
    <xsl:import href="xm_marker_fix.xsl"/>
    <xsl:import href="xm_bookmeta_fix.xsl"/>
    <xsl:import href="xm_attr_set_reflection_mod.xsl"/>
    <xsl:import href="xm_static_content.xsl"/>
    <xsl:import href="xm_common_vars.xsl"/>
    <xsl:import href="xm_titlepage.xsl"/>
    <xsl:import href="xm_layout_masters_overrides.xsl" />
    <xsl:import href="xm_commons_mod.xsl"/>
    <xsl:import href="xm_tables.xsl"/>    
     <xsl:import href="xm_choicetable_fix.xsl" />
     <xsl:import href="xm_index.xsl" />
    <xsl:import href="xm_ui_domain.xsl" />
    <xsl:import href="xm_glossary.xsl" />    
    <xsl:import href="xm_toc.xsl" />    
    <xsl:import href="xm_bookmarks.xsl" />

    <!-- Variables and parameters -->

<!-- Everything above this line should be left unmodified -->

<!-- NEW TEMPLATE START -->
<!-- Use this template to 'replace' characters 'with' other characters in 'text'-->
<xsl:template name="replace-string">
<xsl:param name="text"></xsl:param>
<xsl:param name="replace"></xsl:param>
<xsl:param name="with"></xsl:param>
<xsl:choose>
<xsl:when test="contains($text,$replace)">
<xsl:value-of select="substring-before($text,$replace)"></xsl:value-of>
<xsl:value-of select="$with"></xsl:value-of>
<xsl:call-template name="replace-string">
<xsl:with-param name="text" select="substring-after($text,$replace)"></xsl:with-param>
<xsl:with-param name="replace" select="$replace"></xsl:with-param>
<xsl:with-param name="with" select="$with"></xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"></xsl:value-of>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- NEW TEMPLATE END -->

<!--TEMPLATE OVERRIDE BEGIN - original template: DITA_OT\demo\xmfo\cfg\fo\attrs\pr-domain-attr.xsl-->
<xsl:template match="*[contains(@class,' pr-d/codeph ')]">
<fo:inline xsl:use-attribute-sets="codeph" id="{@id}">

<!-- SUPPRESSING EXISTING LINE <xsl:apply-templates/> -->

<!-- ADD FOLLOWING TO CALL THE NEW TEMPLATE WE DEFINED ABOVE -->
<!-- Call the replace template and get it to replace all "/" characters with "/" followed by a ZERO WIDTH SPACE (U+200B)-->
<xsl:call-template name="replace-string">
<xsl:with-param name="text" select="."></xsl:with-param>
<xsl:with-param name="replace" select="'/'"></xsl:with-param>
<xsl:with-param name="with" select="'/&#x200B;'"></xsl:with-param>
</xsl:call-template>
</fo:inline>
</xsl:template>
<!--TEMPLATE OVERRIDE END -->
    
</xsl:stylesheet>

Remember that you need to duplicate the existing template entirely (as done here) in order to retain anything it was doing before (because an override template entirely replaces the original, it does not extend it). I usually duplicate a template right inside the file it is inside first, then make mods to the duplicate copy while testing. Then once it is working I move everything into the custom.xsl to keep things neat and tidy. Note as well that I comment where any templates I am overriding are by including a reference to the filename. This way, in future versions of the DITA OT specifically, you can find those files and check to see if you need to update your modified version.
« Last Edit: October 26, 2011, 01:27:07 PM by Derek Read » Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #2 on: October 26, 2011, 01:20:49 PM »

Here are some before and after examples.


* line_wrap_on_forward_slash.png (60.41 KB, 919x821 - viewed 781 times.)
Logged
mmoulder
Member

Posts: 43


« Reply #3 on: October 26, 2011, 04:34:46 PM »

Thanks Derek, that was exactly what we were looking for. On a side note, we found that it already breaks on underscores by default, that doesn't help here, but we happened to notice that.
Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #4 on: October 27, 2011, 03:45:13 PM »

Search for 002F (SOLIDUS) on http://unicode.org/reports/tr14/. It discusses the "SY" rule, which actually mentions that URLs containing this character may require special handling (as we have done here).
Logged
Pages: 1
Print
Jump to: