xsl-list
[Top] [All Lists]

Re: [xsl] From WordprocessingML inline styles to nested inline elements

2007-04-02 05:52:58
Wendell,

thank you very much for your comments. (I have been on a leave so I couldn't reply earlier.)

I feel I should have been clearer about the "wicked" things I am trying to do. Please let me have another go. Basically, I am now tackling the task of transforming WordML inline styles in 3 steps:

1) Define the nesting hierarchy of the inline styles in a tiny XML file of its own. E.g.:

<style_nesting>
  <b><i><u/></i></b>
</style_nesting>

2) Apply a meta-stylesheet which will exploit the file from step 1 and generate an operating stylesheet that contains, among other things, template rules for translating the set of a run's "active" inline styles into elements that are properly nested around the run's text.

3) Transform WordML runs with inline styles using the operating stylesheet that resulted from step 2, going from

<w:r>
  <w:rPr>
    <w:i/>
    <w:b/>
  </w:rPr>
  <w:t>This is text in bold and italic.</w:t>
</w:r>

to

<b><i>This is text in bold and italic.</i></b>


All but my last posting as well as your suggestion and David's were based on the assumption that the configuration file is read at the operating stylesheet's run-time, i.e. in step 3. That stylesheet would accordingly only contain generic inline style processing code.

Having changed my mind, I would now like to evaluate the nesting hierarchy already at step 2 and generate a stylesheet with "hard-wired" style nesting for step 3.

Hence, I still have the nesting hierarchy available, but need to make different use of it, by *indirectly* deriving from it XSLT code that "materializes" the nesting of the styles. As I am again mainly interested in the "final", operating stylesheet's contents, I will not consider for the moment how to actually generate that code from the nesting hierarchy in the configuration file.

I can think of two approaches in the operating stylesheet:

a) Using an ordered set of modes (e.g. 1 - unnamed, 2 - style_i,
   3 - style_u etc.). This requires, however, a cascade of all
   the styles that could come next and may be active or not, established
   by the list of modes allowed next:

<xsl:template match="w:r[w:rPr/w:b]">
  <xsl:element name="b">
  <xsl:apply-templates select="." mode="style_i style_u style_x"/>
  </xsl:element>
</xsl:template>

<xsl:template match="w:r[w:rPr/w:i]" mode="style_i">
  <xsl:element name="i">
  <xsl:apply-templates select="." mode="style_u style_x"/>
  </xsl:element>
</xsl:template>

...


b) Using one rule and a recursive named template. This seems to be much more elegant, as the nesting hierarchy is stated just in one place, as a sequence of strings:

<xsl:template match="w:r">
  <xsl:call-template name="add_style">
    <xsl:with-param name="style_names_list"
      select="('b', 'i', 'u', 'NONE')"/>
  </xsl:call-template>
</xsl:template>

<xsl:template name="add_style">
  <xsl:param name="style_names_list"/>

  <xsl:variable name="current_style_name"
    select="$style_names_list[1]"/>

  <xsl:choose>

    <xsl:when test="$current_style_name = 'NONE'">
      <xsl:value-of select="w:t"/>
    </xsl:when>

    <xsl:when test="w:rPr/*[local-name()=$current_style_name]">
      <xsl:element name="{$current_style_name}">
        <xsl:call-template name="add_style">
          <xsl:with-param name="style_names_list"
            select="remove($style_names_list, 1)"/>
        </xsl:call-template>
      </xsl:element>
    </xsl:when>

    <xsl:otherwise>
      <xsl:call-template name="add_style">
        <xsl:with-param name="style_names_list"
          select="remove($style_names_list, 1)"/>
      </xsl:call-template>
    </xsl:otherwise>

  </xsl:choose>

</xsl:template>


The latter solution works almost fine. Just two questions remain:

1) Can you think of better approaches, or do you have suggestions on how to improve the above?

2) I tried, of course, to test for the empty sequence as recursion terminator instead of testing for the token 'NONE'. Unfortunately, neither of the following test expressions worked, with $style_names_list initially set to ('b', 'i', 'u'):

$style_names_list = ()
$current_style_name = ''
$current_style_name = ()

Which is the correct expression to test for the empty sequence that $style_names_list will evaluate to after its last item has been removed?

  Yves


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>