XSLTOperation to edit MathML

Post here questions and problems related to oXygen frameworks/document types.
mboudreau
Posts: 68
Joined: Sat Jan 07, 2017 1:23 am

XSLTOperation to edit MathML

Post by mboudreau »

I'm creating an Author action to add a label to a MathML element.

Following the models at https://www.oxygenxml.com/doc/versions/ ... tions.html, my transformation script looks like this:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:mml="http://www.w3.org/1998/Math/MathML"
    xmlns:oxy="http://www.oxygenxml.com/ns/author/xpath-extension-functions"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs oxy"
    version="2.0">
    
    <xsl:template match="/">
        <xsl:apply-templates select="oxy:current-element()"/>
    </xsl:template>
    
    <xsl:template match="mml:math">
        <xsl:element name="mml:math">
            <xsl:for-each select="@*">
                <xsl:copy/>
            </xsl:for-each>
            <mml:mrow>
                <mml:mtable>
                    <mml:mlabeledtr>
                        <mml:mtd>
                            <mml:mtext>(#)</mml:mtext>
                        </mml:mtd>
                        <mml:mtd>
                            <xsl:apply-templates/>
                        </mml:mtd>
                    </mml:mlabeledtr>
                </mml:mtable>
            </mml:mrow>            
        </xsl:element>
    </xsl:template>
    
    <!-- catchall -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>
I have two questions:

1. Although the XSLTOperation action seems to run the script without errors, when I have it open in Oxygen I get a parsing error: "Cannot find a 0-argument function named Q{http://www.oxygenxml.com/ns/author/xpat ... nt-element()" Is this a bug?

2. The text "(#)" inside the <mml:mtext> element is just a placeholder for the actual label, e.g., "(1)" or "(2)" or "(14.1)", etc. I was hoping to use the editor variable ${ask} to request the actual label from the user, but I don't seem to have the syntax right. E.g., <xsl:value-of select="${ask('Enter label', generic)}"/> doesn't work. Is there a way to do this?
alex_jitianu
Posts: 1007
Joined: Wed Nov 16, 2005 11:11 am

Re: XSLTOperation to edit MathML

Post by alex_jitianu »

Hello,

1. Yes, it is something we've overlooked. The XSLT editor should recognize this oxy:current-element() function. I will add an issue to fix this behavior.
2. The operation has a expandEditorVariables parameter which is set by default. It replaces variables from the returned result. So, for example, if your result looks like this, the user will be asked for the value and the value will be replaced in the result before inserting it in the document.

Code: Select all

<mml:mtext>(${ask('Enter label', generic)})</mml:mtext>
If you need do some condition based on the value, then you need to pass it to the XSLTOperation as a parameter, through the externalParams operation parameter.

Code: Select all

condition=${ask('Enter label', generic)
The XSLT can then use the condition parameter:

Code: Select all

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:param name="condition"/>
    
    <xsl:template match="/">
        <xsl:if test="$condition = '1'"></xsl:if>
    </xsl:template>
</xsl:stylesheet>
Best regards,
Alex
mboudreau
Posts: 68
Joined: Sat Jan 07, 2017 1:23 am

Re: XSLTOperation to edit MathML

Post by mboudreau »

Hi Alex,

The ${ask} editor variable isn't working as you describe. When my template includes this:

Code: Select all

<mml:mtext>${ask('Enter label', generic)}</mml:mtext>
I get exactly the same content in the output. No dialog box appears asking for the value, and the string "${ask('Enter label', generic)}" appears in the MathML output.

I'm using Oxygen 23.0 build 2020111805. XSLTOperation has the following arguments:
  • sourceLocation: [empty]
  • targetLocation: [empty]
  • script: ${framework}/xslt/add_df_label.xsl
  • action: Replace
  • caretPosition: First editable position
  • expandEditorVariables: true
  • suspendTrackChanges: false
  • externalParams: [empty]
alex_jitianu
Posts: 1007
Joined: Wed Nov 16, 2005 11:11 am

Re: XSLTOperation to edit MathML

Post by alex_jitianu »

Hello

You are correct. It appears that the expandEditorVariables doesn't treat the $ask variables. I will update the documentation to make that clear. Meanwhile, please try my second approach, the one with parameters.

Best regards,
Alex
mboudreau
Posts: 68
Joined: Sat Jan 07, 2017 1:23 am

Re: XSLTOperation to edit MathML

Post by mboudreau »

Hi Alex,

Using a parameter worked. For XSLTOperation:
  • externalParams: label=${ask('Enter label', generic)}
And the script:

Code: Select all

<xsl:stylesheet 
    xmlns:mml="http://www.w3.org/1998/Math/MathML"
    xmlns:oxy="http://www.oxygenxml.com/ns/author/xpath-extension-functions"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs oxy"
    version="2.0">
    
    <xsl:param name="label"/>
    
    <xsl:template match="/">
        <xsl:apply-templates select="oxy:current-element()"/>
    </xsl:template>
    
    <xsl:template match="mml:math">
        <xsl:element name="mml:math">
            <xsl:for-each select="@*">
                <xsl:copy/>
            </xsl:for-each>
            <mml:mrow>
                <mml:mtable>
                    <mml:mlabeledtr>
                        <mml:mtd>
                            <mml:mtext><xsl:value-of select="$label"/></mml:mtext>
                        </mml:mtd>
                        <mml:mtd>
                            <xsl:apply-templates/>
                        </mml:mtd>
                    </mml:mlabeledtr>
                </mml:mtable>
            </mml:mrow>            
        </xsl:element>
    </xsl:template>
    
    <!-- catchall -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>
Thanks for your help!
Post Reply