apply-imports / next-match missing in org.dita-community.dita3html

Post here questions and problems related to editing and publishing DITA content.
jcb_mgc
Posts: 8
Joined: Thu Sep 10, 2020 7:03 pm

apply-imports / next-match missing in org.dita-community.dita3html

Post by jcb_mgc »

Hi,
We have a custom DITA-OT plugin that overrides several templates in the base xhtml plugin. One of these is gen-user-scripts.

In testing, our plugin in the oXygen environment, I found that our gen-user-scripts override is not being called at all. The problem seems to be that the gen-user-scripts override in the org.dita-community-dita3html plugin is not chaining template calls with xsl:apply-templates or xsl:next-match.

This is the template from the org.dita-commity-dita3html plugin. I inserted a comment where the call should go:

Code: Select all

<xsl:template mode="gen-user-scripts" match="*[contains(@class, ' topic/topic ')]">
    <xsl:choose>
      <xsl:when test="$mathJaxUseCDNLinkBoolean">
        <!-- Reference to MathMax script as served over the public Web: -->
        <script type="text/javascript"
          src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?{$mathJaxConfigParam}">
        </script>    
      </xsl:when>
      <xsl:when test="$mathJaxUseLocalLinkBoolean">
        <xsl:if test="$mathJaxLocalJavascriptUri = ''">
          <xsl:message> - [WARN] Runtime parameter $mathJaxUseLocalLinkBoolean is true but $mathJaxLocalJavascriptUri is not set. </xsl:message>
        </xsl:if>
        <script type="text/javascript"
          src="{$mathJaxLocalJavascriptUri}?{$mathJaxConfigParam}">
        </script>    
      </xsl:when>
      <xsl:otherwise>
        <!-- Do not use MathJax Javascript library -->
      </xsl:otherwise>
    </xsl:choose>
    <!-- TEMPLATE CHAINING...CALL xsl:apply-imports SHOULD BE HERE -->
  </xsl:template>
I found that if I add a call to xsl:apply-imports at the point where the "TEMPLATE CHAINING" comment is, then our own gen-user-scripts template is called.

I can fix this locally for now, but I wonder if a change request should be filed against the org.dita-community.dita2html plugin. I did not investigate whether there are other places where apply-imports should be called.

Thanks,
JCB
Radu
Posts: 9049
Joined: Fri Jul 09, 2004 5:18 pm

Re: apply-imports / next-match missing in org.dita-community.dita3html

Post by Radu »

Hi,

Thanks for the report, I added an issue on the plugin's project:

https://github.com/dita-community/dita1 ... t/issues/8

and I also added an internal issue to look into fixing this on our side. These plugins are quite old but they still contain some functionality related to mathml and svg handling which is not in the DITA OT code.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
jcb_mgc
Posts: 8
Joined: Thu Sep 10, 2020 7:03 pm

Re: apply-imports / next-match missing in org.dita-community.dita3html

Post by jcb_mgc »

Hi Radu thanks for looking into that issue.

This is actually something we've been wondering about for a long time. So far, we have been using DITA-OT with our own plugin, and we have been the only fish in the pond. Now we are migrating to oXygen and that's not the case anymore.

We don't have calls to apply-imports or next-match in our own plugin - we haven't had to worry about it. As I add them, I know it's quite likely I will find cases where calling the next plugin will produce incorrect content for us. It's also possible that a plugin that executes before us could cause problems.

Do you have a general strategy for handling this? It seems wrong to not call the next plugin. It seems like it breaks the whole system. Our plugin will never be released into the wild, but we still have to coexist. It could become quite a job to have to address this with each oXygen and/or DITA-OT update.

Would it be considered as a design flaw in our DITA customizations if we find such cases -- where we have to interrupt and stop the stream of processing in order to produce the desired content with DITA-OT?

Thanks again!
John
Radu
Posts: 9049
Joined: Fri Jul 09, 2004 5:18 pm

Re: apply-imports / next-match missing in org.dita-community.dita3html

Post by Radu »

Hi John,

Indeed DITA OT plugins which override the same extension points and add XSLTs may interfere with each other.
Well one option would be to continue to use your custom DITA OT distribution with Oxygen, in the Oxygen Preferences->DITA page you can add a reference to your custom DITA OT folder.
Another option might be to create your own transformation type, copy the entire XHTML plugin and make your own version of it. But you would need to maintain your plugin and maybe update it with the latest changes when new DITA OT versions come up.
Another option would be that when you add your plugins to Oxygen's bundled DITA-OT/plugins folder to remove the dita-community ones (if you are not using embedded MathML and SVG content), then run the DITA OT integrator.
As on Windows Oxygen is usually installed in the Program Files folder, usually you need administrator rights to add and delete plugins to the DITA-OT/plugins folder, then run the DITA OT integrator. So we usually recommend copying the entire DITA-OT folder from Oxygen to an outside location and then go to the Preferences->DITA page and refer to that custom DITA OT installation.
Maybe you could also perform some automated tests, on an integration server which would handle the publishing using a custom company specific DITA OT version after publishing you could run some scripts through the produced HTML content, see if it retains your XSLT customizations. In this way when you update to newer DITA OT versions your tests would start failing on the integration server if your XSLT templates no longer matches anything.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
Radu
Posts: 9049
Joined: Fri Jul 09, 2004 5:18 pm

Re: apply-imports / next-match missing in org.dita-community.dita3html

Post by Radu »

Hi John,

We released Oxygen 23 and its bundled DITA OT has a fix on that particular xsl:template to apply a next-match.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
chrispitude
Posts: 907
Joined: Thu May 02, 2019 2:32 pm

Re: apply-imports / next-match missing in org.dita-community.dita3html

Post by chrispitude »

jcb_mgc wrote: Fri Sep 11, 2020 6:11 pmThis is actually something we've been wondering about for a long time. So far, we have been using DITA-OT with our own plugin, and we have been the only fish in the pond. Now we are migrating to oXygen and that's not the case anymore.

We don't have calls to apply-imports or next-match in our own plugin - we haven't had to worry about it. As I add them, I know it's quite likely I will find cases where calling the next plugin will produce incorrect content for us. It's also possible that a plugin that executes before us could cause problems.
Hi John,

I've been learning some things on this same topic.

<xsl:next-match> calls the next matching template in line for the context node. I suppose that there are multiple ways your own template might need to interact with surrounding templates:
  • Generate your template's output for the context node first, then always concatenate the <xsl:next-match> output afterwards
  • Generate the <xsl:next-match> output for the context node first, then always concatenate your template's output afterwards
  • Generate your template's output or the <xsl:next-match> output only, depending on some case
  • Put the <xsl:next-match> output in a variable, then have your template post-process it and generate output
  • Put your template output in a variable, then apply templates (not <xsl:next-match>) to that
As an example of the last one, I wanted to add an attribute to <p> elements in the input document under certain circumstances:

post59828.html#p59828

Of course, you can't modify the input document in XSLT, so I had to make my own copy of the context node, modify it, and apply templates to that (and make sure my own template doesn't match on the copy or it infinite-loops). And that wasn't enough because some downstream templates take conditional action depending on the element's parent element type, so I actually had to create a fake parent element, *then* create my copy inside that, then apply templates to my copy in its fake-parent context:

Code: Select all

  <!-- add @outputclass="keep-with-next" for <p> ending in ":" or "," -->
  <!-- (this must require that @outputclass not contain "keep-with-next" to avoid an infinite template loop) -->
  <xsl:template match="*[contains(@class, ' topic/p ')][matches(., '[,|:]$')][not(tokenize(@outputclass, '\s+') = 'keep-with-next')]" priority="101">
    <xsl:call-template name="snps-add-keep-with-next"/>
  </xsl:template>
 
  <!-- this is a reusable template that adds @outputclass="keep-with-next" to a <p> element-->
  <xsl:template name="snps-add-keep-with-next">
    <!-- make a copy of the <p> element, but add @outputclass="keep-with-next" -->
    <xsl:variable name="p" as="node()">
      <topic class="- topic/topic ">  <!-- do this for PDF Chemistry index-entry processing that checks if we're in topic content -->
        <xsl:copy select=".">
          <xsl:sequence select="@* except @outputclass"/>
          <xsl:attribute name="outputclass" select="string-join(('keep-with-next', tokenize(@outputclass, '\s+')), ' ')"/>
          <xsl:sequence select="node()"/>
        </xsl:copy>
      </topic>
    </xsl:variable>

    <!-- process it in the usual way; its results are returned as our results -->
    <xsl:apply-templates select="$p/*"/>  <!-- select the <p>, not the parent dummy topic -->
  </xsl:template>
Post Reply