[yelp-xsl/wip/if-1-0] Refactoring Mallard conditional processing



commit 3592925b5a2fb357e2db2b338cc01714d3ccd6d0
Author: Shaun McCance <shaunm gnome org>
Date:   Tue Jan 17 15:21:09 2012 -0500

    Refactoring Mallard conditional processing

 xslt/mallard/common/mal-if.xsl       |  287 ++++++++++++++++++++++------------
 xslt/mallard/html/mal2html-block.xsl |  121 ++++++++++-----
 xslt/mallard/html/mal2html-list.xsl  |   77 ++++++++--
 xslt/mallard/html/mal2html-media.xsl |   27 +++-
 xslt/mallard/html/mal2html-page.xsl  |   16 ++
 xslt/mallard/html/mal2html-svg.xsl   |   20 ++-
 xslt/mallard/html/mal2html-table.xsl |    6 +-
 xslt/mallard/html/mal2html.xsl       |    7 +-
 xslt/mallard/html/mal2xhtml.xsl      |    6 +-
 9 files changed, 400 insertions(+), 167 deletions(-)
---
diff --git a/xslt/mallard/common/mal-if.xsl b/xslt/mallard/common/mal-if.xsl
index a26a21e..b1ed7af 100644
--- a/xslt/mallard/common/mal-if.xsl
+++ b/xslt/mallard/common/mal-if.xsl
@@ -37,149 +37,228 @@ in Mallard documents.
 
 
 <!--@@==========================================================================
-mal.if.env
-The list of env strings.
-:Revision:version="1.0" date="2011-04-28" status="review"
+mal.if.target
+The list of supported target tokens.
+:Revision:version="1.0" date="2012-01-17" status="review"
+
+This parameter takes a space-separated list of tokens to enable for conditional
+processing. It is used by the template *{mal.if.test}. This parameter is meant
+to hold tokens starting with #{target:}. It should usually be set by the primary
+importing stylesheet.
+-->
+<xsl:param name="mal.if.target" select="''"/>
+
+
+<!--@@==========================================================================
+mal.if.platform
+The list of supported platform tokens.
+:Revision:version="1.0" date="2012-01-17" status="review"
 
-This parameter takes a space-separated list of strings for the #{if:env}
-conditional processing function. The #{if:env} function will return #{true}
-if its argument is in this list.
+This parameter takes a space-separated list of tokens to enable for conditional
+processing. It is used by the template *{mal.if.test}. This parameter is meant
+to hold tokens starting with #{platform:}. It should usually be set by hand or
+by a customization stylesheet.
 -->
-<xsl:param name="mal.if.env" select="''"/>
-<xsl:variable name="_mal.if.env" select="concat(' ', $mal.if.env, ' ')"/>
+<xsl:param name="mal.if.platform" select="''"/>
 
 
 <!--@@==========================================================================
-mal.if.supports
-The list of supported technologies.
-:Revision:version="1.0" date="2011-07-31" status="review"
+mal.if.features
+The list of supported feature tokens.
+:Revision:version="1.0" date="2012-01-17" status="review"
+
+This parameter takes a space-separated list of tokens to enable for conditional
+processing. It is used by the template *{mal.if.test}. This parameter is meant
+to hold tokens that specify the capabilities of these stylesheets. It should
+usually be set by the primary importing stylesheet.
+-->
+<xsl:param name="mal.if.features" select="'
+mallard:1.0
+'"/>
 
-This parameter takes a space-separated list of strings for the #{if:supports}
-conditional processing function. The #{if:supports} function will return #{true}
-if its argument is in this list or @{mal.if.supports.custom}.
 
-Do not change this parameter unless you are completely overriding the behavior
-of these stylesheets in a way that removes or changes features. To add support
-in a customization, use the @{mal.if.supports.custom} parameter.
+<!--@@==========================================================================
+mal.if.custom
+A custom list of supported tokens.
+:Revision:version="1.0" date="2012-01-17" status="review"
+
+This parameter takes a space-separated list of tokens to enable for conditional
+processing. It is used by the template *{mal.if.test}. This parameter is meant
+to hold extra values enabled by hand or by a customization stylesheet.
 -->
-<xsl:param name="mal.if.supports" select="'1.0'"/>
+<xsl:param name="mal.if.custom" select="''"/>
 
 
 <!--@@==========================================================================
-mal.if.supports.custom
-The list of technologies supported by customizations.
-:Revision:version="1.0" date="2011-07-31" status="review"
+mal.if.maybe
+A list of tokens that may be true.
+:Revision:version="1.0" date="2012-01-17" status="review"
 
-This parameter takes a space-separated list of strings for the #{if:supports}
-conditional processing function. The #{if:supports} function will return #{true}
-if its argument is in this list or @{mal.if.supports}.
+This parameter takes a space-separated list of tokens that may be true. The
+template *{mal.if.test} returns special flags when a condition may be true,
+allowing conditional processing to be deferred (for example, to CSS media
+selectors). This parameter should usually be set by the primary importing
+stylesheet.
 -->
-<xsl:param name="mal.if.supports.custom" select="'1.0'"/>
+<xsl:param name="mal.if.maybe" select="''"/>
 
 
-<xsl:variable name="_mal.if.supports"
-              select="concat(' ', $mal.if.supports, ' ', $mal.if.supports.custom, ' ')"/>
+<xsl:variable name="_mal.if.tokens" select="concat(' ', $mal.if.target,
+                                                   ' ', $mal.if.platform,
+                                                   ' ', $mal.if.features,
+                                                   ' ', $mal.if.custom,
+                                                   ' ')"/>
+<xsl:variable name="_mal.if.maybe" select="concat(' ', $mal.if.maybe, ' ')"/>
 
 
 <!--**==========================================================================
 mal.if.test
 Test if a condition is true.
-:Revision:version="1.0" date="2011-04-28" status="review"
+:Revision:version="1.0" date="2012-01-17" status="review"
 $node: The element to check the condition for.
-$test: The XPath expression to check.
+$test: The test expression.
+
+This template evaluates the test expression ${test}, which is taken automatically
+from the #{test} or #{if:test} attribute of $node. It splits the expression on
+commas into subexpression, then splits each subexpression on spaces into tokens.
+A token is taken to be true if it's in one of the space-separated lists from
+ {mal if target}, @{mal.if.platform}, @{mal.if.features}, or @{mal.if.custom}.
+If the token starts with an examation point, the exclamation point is stripped
+and the resulting truth value is negated.
+
+A subexpression is true if all its tokens is true. The full test expression is
+true if any subexpression is true. If the test expression is true, the literal
+string #{'true'} is returned. If the test expression is false, the empty
+string is returned.
 
-This template tests whether the ${test} is true, evaluating it with
-the Mallard conditional functions. The ${test} parameter is expected
-to be a valid XPath expression. If not provided, it defaults to the
-#{if:test} attribute of ${node}, or the non-namespaced #{test}
-attribute if ${node} is an #{if:if} or #{if:when} element.
+This template can handle "maybe" values: tokens that may or may not be true,
+and whose truth values are deferred to post-transform time. A token is maybe
+if it appears in the space-separated list @{mal.if.maybe}. If a subexpression
+contains a maybe value and does not contain any false tokens, its truth value
+is a special string constructed from the maybe tokens and starting with the
+string #{if__}. If any subexpressions are maybe and none of the subexpressions
+are false, the return value is a space-separated list of the maybe strings.
 
-If ${test} evaluates to #{true}, this template outputs the literal
-string #{'true'}. Otherwise, it outputs nothing.
+Maybe tokens usually must be handled specifically by the importing stylesheet.
+It's usually not sufficient to just add a token to @{mal.if.maybe}. This
+template will handle any maybe token, but it does not handle the actual logic
+of dynamically showing or hiding content based on those tokens.
 -->
 <xsl:template name="mal.if.test">
   <xsl:param name="node" select="."/>
-  <xsl:param name="test" select="$node/self::if:if/@test |
-                                 $node/self::if:when/@test |
-                                 $node[not(self::if:when)]/@if:test "/>
+  <xsl:param name="test" select="($node/self::if:if/@test |
+                                  $node/self::if:when/@test |
+                                  $node/@if:test)[1]"/>
   <xsl:choose>
-    <xsl:when test="string($test) = ''">
-      <xsl:text>true</xsl:text>
+    <xsl:when test="$test != ''">
+      <xsl:variable name="ret">
+        <xsl:for-each select="str:split($test, ',')">
+          <xsl:text> </xsl:text>
+          <xsl:variable name="subexpr">
+            <xsl:for-each select="str:tokenize(., ' ')">
+              <xsl:text> </xsl:text>
+              <xsl:choose>
+                <xsl:when test="starts-with(., '!')">
+                  <xsl:variable name="tmp">
+                    <xsl:call-template name="_mal.if.test.check_token">
+                      <xsl:with-param name="token" select="substring(., 2)"/>
+                    </xsl:call-template>
+                  </xsl:variable>
+                  <xsl:choose>
+                    <xsl:when test="$tmp = '1'">
+                      <xsl:text>0</xsl:text>
+                    </xsl:when>
+                    <xsl:when test="$tmp = '0'">
+                      <xsl:text>1</xsl:text>
+                    </xsl:when>
+                    <xsl:otherwise>
+                      <xsl:value-of select="concat('not-', $tmp)"/>
+                    </xsl:otherwise>
+                  </xsl:choose>
+                </xsl:when>
+                <xsl:otherwise>
+                  <xsl:call-template name="_mal.if.test.check_token">
+                    <xsl:with-param name="token" select="."/>
+                  </xsl:call-template>
+                </xsl:otherwise>
+              </xsl:choose>
+              <xsl:text> </xsl:text>
+            </xsl:for-each>
+          </xsl:variable>
+          <xsl:choose>
+            <xsl:when test="contains($subexpr, ' 0 ')">
+              <xsl:text></xsl:text>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:variable name="subcond">
+                <xsl:for-each select="str:tokenize($subexpr, ' ')[.!='1']">
+                  <xsl:if test="position != 1">
+                    <xsl:text>__</xsl:text>
+                  </xsl:if>
+                  <xsl:value-of select="."/>
+                </xsl:for-each>
+              </xsl:variable>
+              <xsl:choose>
+                <xsl:when test="$subcond != ''">
+                  <xsl:text>if__</xsl:text>
+                  <xsl:value-of select="$subcond"/>
+                </xsl:when>
+                <xsl:otherwise>
+                  <xsl:text>true</xsl:text>
+                </xsl:otherwise>
+              </xsl:choose>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:for-each>
+        <xsl:text> </xsl:text>
+      </xsl:variable>
+      <xsl:choose>
+        <xsl:when test="contains($ret, ' true ')">
+          <xsl:text>true</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:for-each select="str:split($ret, ' ')[. != 'true']">
+            <xsl:value-of select="."/>
+            <xsl:text> </xsl:text>
+          </xsl:for-each>
+        </xsl:otherwise>
+      </xsl:choose>
     </xsl:when>
-    <xsl:when test="dyn:evaluate($test)">
+    <xsl:otherwise>
       <xsl:text>true</xsl:text>
-    </xsl:when>
+    </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
 
-
-<!--**==========================================================================
-mal.if.choose
-Gets the position of the first matching condition in #{if:choose}
-:Revision:version="1.0" date="2011-04-28" status="review"
-$node: The #{if:choose} element to check.
-
-The #{if:choose} element takes a list of #{if:when} elements, optionally followed
-by an #{if:else} element. Given an #{if:choose} element, this template outputs
-the position of the first #{if:when} whose #{test} attribute evaluates to #{true}.
-If no #{if:when} elements are true, the output is empty.
--->
-<xsl:template name="mal.if.choose">
-  <xsl:param name="node" select="."/>
-  <xsl:if test="if:when[1]">
-    <xsl:call-template name="_mal.if.choose.try">
-      <xsl:with-param name="node" select="if:when[1]"/>
-      <xsl:with-param name="pos" select="1"/>
-    </xsl:call-template>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="_mal.if.choose.try">
-  <xsl:param name="node"/>
-  <xsl:param name="pos"/>
-  <xsl:variable name="if">
-    <xsl:call-template name="mal.if.test">
-      <xsl:with-param name="node" select="$node"/>
-    </xsl:call-template>
-  </xsl:variable>
+<xsl:template name="_mal.if.test.check_token">
+  <xsl:param name="token"/>
   <xsl:choose>
-    <xsl:when test="$if = 'true'">
-      <xsl:value-of select="$pos"/>
+    <xsl:when test="contains($_mal.if.tokens, concat(' ', $token, ' '))">
+      <xsl:text>1</xsl:text>
     </xsl:when>
-    <xsl:when test="$node/following-sibling::if:when[1]">
-      <xsl:call-template name="_mal.if.choose.try">
-        <xsl:with-param name="node" select="$node/following-sibling::if:when[1]"/>
-        <xsl:with-param name="pos" select="$pos + 1"/>
+    <xsl:when test="contains($_mal.if.maybe, concat(' ', $token, ' '))">
+      <xsl:call-template name="_mal.if.test.flatten_token">
+        <xsl:with-param name="token" select="$token"/>
       </xsl:call-template>
     </xsl:when>
-  </xsl:choose>
-</xsl:template>
-
-
-<!-- ======================================================================= -->
-
-<func:function name="if:env">
-  <xsl:param name="env"/>
-  <xsl:choose>
-    <xsl:when test="contains($_mal.if.env, $env)">
-      <func:result select="true()"/>
-    </xsl:when>
     <xsl:otherwise>
-      <func:result select="false()"/>
+      <xsl:text>0</xsl:text>
     </xsl:otherwise>
   </xsl:choose>
-</func:function>
+</xsl:template>
 
-<func:function name="if:supports">
-  <xsl:param name="tech"/>
-  <xsl:choose>
-    <xsl:when test="contains($_mal.if.supports, $tech)">
-      <func:result select="true()"/>
-    </xsl:when>
-    <xsl:otherwise>
-      <func:result select="false()"/>
-    </xsl:otherwise>
-  </xsl:choose>
-</func:function>
+<xsl:template name="_mal.if.test.flatten_token">
+  <xsl:param name="token"/>
+  <xsl:for-each select="str:split($token, '')">
+    <xsl:choose>
+      <xsl:when test="contains('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_', .)">
+        <xsl:value-of select="."/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:text>-</xsl:text>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:for-each>
+</xsl:template>
 
 </xsl:stylesheet>
diff --git a/xslt/mallard/html/mal2html-block.xsl b/xslt/mallard/html/mal2html-block.xsl
index 40072d6..ec1ff06 100644
--- a/xslt/mallard/html/mal2html-block.xsl
+++ b/xslt/mallard/html/mal2html-block.xsl
@@ -51,7 +51,7 @@ syntax highlighting support based on the #{mime} attribute of ${node}.
 <xsl:template name="mal2html.pre">
   <xsl:param name="node" select="."/>
   <xsl:param name="numbered" select="contains(concat(' ', @style, ' '), 'numbered')"/>
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
   <xsl:variable name="first" select="$node/node()[1]/self::text()"/>
   <xsl:variable name="last" select="$node/node()[last()]/self::text()"/>
   <div>
@@ -60,6 +60,10 @@ syntax highlighting support based on the #{mime} attribute of ${node}.
     </xsl:call-template>
     <xsl:attribute name="class">
       <xsl:value-of select="local-name($node)"/>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
     </xsl:attribute>
     <xsl:if test="$numbered">
       <pre class="numbered"><xsl:call-template name="utils.linenumbering">
@@ -201,7 +205,7 @@ in accordance with the Mallard specification on fallback block content.
 
 <!-- = comment = -->
 <xsl:template mode="mal2html.block.mode" match="mal:comment">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
   <xsl:if test="$mal2html.editor_mode
                 or processing-instruction('mal2html.show_comment')">
     <div>
@@ -211,6 +215,10 @@ in accordance with the Mallard specification on fallback block content.
         <xsl:if test="mal:title and @ui:expanded">
           <xsl:text> ui-expander</xsl:text>
         </xsl:if>
+        <xsl:if test="$if != 'true'">
+          <xsl:text> if-if </xsl:text>
+          <xsl:value-of select="$if"/>
+        </xsl:if>
       </xsl:attribute>
       <xsl:call-template name="mal2html.ui.expander.data"/>
       <div class="inner">
@@ -273,8 +281,15 @@ in accordance with the Mallard specification on fallback block content.
 
 <!-- = example = -->
 <xsl:template mode="mal2html.block.mode" match="mal:example">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
-  <div class="example">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
+  <div>
+    <xsl:attribute name="class">
+      <xsl:text>example</xsl:text>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
+    </xsl:attribute>
     <xsl:call-template name="html.lang.attrs"/>
     <xsl:apply-templates mode="mal2html.block.mode"/>
   </div>
@@ -283,7 +298,7 @@ in accordance with the Mallard specification on fallback block content.
 
 <!-- = figure = -->
 <xsl:template mode="mal2html.block.mode" match="mal:figure">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
   <div>
     <xsl:call-template name="html.lang.attrs"/>
     <xsl:attribute name="class">
@@ -291,6 +306,10 @@ in accordance with the Mallard specification on fallback block content.
       <xsl:if test="mal:title and @ui:expanded">
         <xsl:text> ui-expander</xsl:text>
       </xsl:if>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
     </xsl:attribute>
     <xsl:call-template name="mal2html.ui.expander.data"/>
     <div class="inner">
@@ -322,7 +341,7 @@ in accordance with the Mallard specification on fallback block content.
 
 <!-- = listing = -->
 <xsl:template mode="mal2html.block.mode" match="mal:listing">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
   <div>
     <xsl:call-template name="html.lang.attrs"/>
     <xsl:attribute name="class">
@@ -330,6 +349,10 @@ in accordance with the Mallard specification on fallback block content.
       <xsl:if test="mal:title and @ui:expanded">
         <xsl:text> ui-expander</xsl:text>
       </xsl:if>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
     </xsl:attribute>
     <xsl:call-template name="mal2html.ui.expander.data"/>
     <div class="inner">
@@ -349,7 +372,7 @@ in accordance with the Mallard specification on fallback block content.
 
 <!-- = note = -->
 <xsl:template mode="mal2html.block.mode" match="mal:note">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
   <xsl:variable name="notestyle">
     <xsl:choose>
       <xsl:when test="contains(concat(' ', @style, ' '), ' advanced ')">
@@ -385,6 +408,10 @@ in accordance with the Mallard specification on fallback block content.
       <xsl:if test="mal:title and @ui:expanded">
         <xsl:text> ui-expander</xsl:text>
       </xsl:if>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
     </xsl:attribute>
     <xsl:attribute name="title">
       <xsl:call-template name="l10n.gettext">
@@ -414,8 +441,15 @@ in accordance with the Mallard specification on fallback block content.
 
 <!-- = p = -->
 <xsl:template mode="mal2html.block.mode" match="mal:p">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
-  <p class="p">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
+  <p>
+    <xsl:attribute name="class">
+      <xsl:text>p</xsl:text>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
+    </xsl:attribute>
     <xsl:call-template name="html.lang.attrs"/>
     <xsl:apply-templates mode="mal2html.inline.mode"/>
   </p>
@@ -424,7 +458,7 @@ in accordance with the Mallard specification on fallback block content.
 
 <!-- = quote = -->
 <xsl:template mode="mal2html.block.mode" match="mal:quote">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
   <div>
     <xsl:call-template name="html.lang.attrs"/>
     <xsl:attribute name="class">
@@ -432,6 +466,10 @@ in accordance with the Mallard specification on fallback block content.
       <xsl:if test="mal:title and @ui:expanded">
         <xsl:text> ui-expander</xsl:text>
       </xsl:if>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
     </xsl:attribute>
     <xsl:call-template name="mal2html.ui.expander.data"/>
     <div class="inner">
@@ -479,7 +517,7 @@ in accordance with the Mallard specification on fallback block content.
 
 <!-- = synopsis = -->
 <xsl:template mode="mal2html.block.mode" match="mal:synopsis">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
   <div>
     <xsl:call-template name="html.lang.attrs"/>
     <xsl:attribute name="class">
@@ -487,6 +525,10 @@ in accordance with the Mallard specification on fallback block content.
       <xsl:if test="mal:title and @ui:expanded">
         <xsl:text> ui-expander</xsl:text>
       </xsl:if>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
     </xsl:attribute>
     <xsl:call-template name="mal2html.ui.expander.data"/>
     <div class="inner">
@@ -529,26 +571,7 @@ in accordance with the Mallard specification on fallback block content.
 
 <!-- = if:choose = -->
 <xsl:template mode="mal2html.block.mode" match="if:choose">
-  <xsl:variable name="pos">
-    <xsl:call-template name="mal.if.choose"/>
-  </xsl:variable>
-  <xsl:choose>
-    <xsl:when test="$pos != ''">
-      <xsl:apply-templates mode="mal2html.block.mode" select="if:when[position() = number($pos)]/*"/>
-    </xsl:when>
-    <xsl:otherwise>
-      <xsl:for-each select="if:when[last()]/following-sibling::*">
-        <xsl:choose>
-          <xsl:when test="self::if:else">
-            <xsl:apply-templates mode="mal2html.block.mode" select="*"/>
-          </xsl:when>
-          <xsl:otherwise>
-            <xsl:apply-templates mode="mal2html.block.mode" select="."/>
-          </xsl:otherwise>
-        </xsl:choose>
-      </xsl:for-each>
-    </xsl:otherwise>
-  </xsl:choose>
+  <xsl:apply-templates mode="_mal2html.choose.mode" select="if:when[1]"/>
 </xsl:template>
 
 <!-- = if:if = -->
@@ -561,12 +584,36 @@ in accordance with the Mallard specification on fallback block content.
   </xsl:if>
 </xsl:template>
 
-<xsl:template mode="mal2html.block.mode" match="if:when | if:else">
-  <xsl:message>
-    <xsl:text>Conditional element </xsl:text>
-    <xsl:value-of select="local-name(.)"/>
-    <xsl:text> encountered outside of choose</xsl:text>
-  </xsl:message>
+<xsl:template mode="_mal2html.choose.mode" match="if:when">
+  <xsl:variable name="if">
+    <xsl:call-template name="mal.if.test"/>
+  </xsl:variable>
+  <xsl:choose>
+    <xsl:when test="$if = 'true'">
+      <xsl:apply-templates mode="mal2html.block.mode"/>
+    </xsl:when>
+    <xsl:when test="$if != ''">
+      <div class="if-choose {$if}">
+        <div class="if-when">
+          <xsl:apply-templates mode="mal2html.block.mode"/>
+        </div>
+        <div class="if-else">
+          <xsl:apply-templates mode="_mal2html.choose.mode" select="following-sibling::*[1]"/>
+        </div>
+      </div>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates mode="_mal2html.choose.mode" select="following-sibling::*[1]"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template mode="_mal2html.choose.mode" match="if:else">
+  <xsl:apply-templates mode="mal2html.block.mode"/>
+</xsl:template>
+
+<xsl:template mode="_mal2html.choose.mode" match="*">
+  <xsl:apply-templates mode="mal2html.block.mode" select=". | following-sibling::*"/>
 </xsl:template>
 
 </xsl:stylesheet>
diff --git a/xslt/mallard/html/mal2html-list.xsl b/xslt/mallard/html/mal2html-list.xsl
index 4160f77..c05107e 100644
--- a/xslt/mallard/html/mal2html-list.xsl
+++ b/xslt/mallard/html/mal2html-list.xsl
@@ -36,7 +36,7 @@ as well as any special processing for child #{item} elements.
 
 <!-- = list = -->
 <xsl:template mode="mal2html.block.mode" match="mal:list">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
   <xsl:variable name="style" select="concat(' ', @style, ' ')"/>
   <xsl:variable name="el">
     <xsl:choose>
@@ -57,6 +57,10 @@ as well as any special processing for child #{item} elements.
       <xsl:if test="mal:title and @ui:expanded">
         <xsl:text> ui-expander</xsl:text>
       </xsl:if>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
     </xsl:attribute>
     <xsl:call-template name="mal2html.ui.expander.data"/>
     <div class="inner">
@@ -84,8 +88,15 @@ as well as any special processing for child #{item} elements.
 
 <!-- = list/item = -->
 <xsl:template match="mal:list/mal:item">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
-  <li class="list">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
+  <li>
+    <xsl:attribute name="class">
+      <xsl:text>list</xsl:text>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
+    </xsl:attribute>
     <xsl:call-template name="html.lang.attrs"/>
     <xsl:apply-templates mode="mal2html.block.mode"/>
   </li>
@@ -94,7 +105,7 @@ as well as any special processing for child #{item} elements.
 
 <!-- = steps = -->
 <xsl:template mode="mal2html.block.mode" match="mal:steps">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
   <div>
     <xsl:call-template name="html.lang.attrs"/>
     <xsl:attribute name="class">
@@ -102,6 +113,10 @@ as well as any special processing for child #{item} elements.
       <xsl:if test="mal:title and @ui:expanded">
         <xsl:text> ui-expander</xsl:text>
       </xsl:if>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
     </xsl:attribute>
     <xsl:call-template name="mal2html.ui.expander.data"/>
     <div class="inner">
@@ -118,8 +133,15 @@ as well as any special processing for child #{item} elements.
 
 <!-- = steps/item = -->
 <xsl:template match="mal:steps/mal:item">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
-  <li class="steps">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
+  <li>
+    <xsl:attribute name="class">
+      <xsl:text>steps</xsl:text>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
+    </xsl:attribute>
     <xsl:call-template name="html.lang.attrs"/>
     <xsl:apply-templates mode="mal2html.block.mode"/>
   </li>
@@ -128,7 +150,7 @@ as well as any special processing for child #{item} elements.
 
 <!-- = terms = -->
 <xsl:template mode="mal2html.block.mode" match="mal:terms">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
   <xsl:variable name="style" select="concat(' ', @style, ' ')"/>
   <div>
     <xsl:call-template name="html.lang.attrs"/>
@@ -137,6 +159,10 @@ as well as any special processing for child #{item} elements.
       <xsl:if test="mal:title and @ui:expanded">
         <xsl:text> ui-expander</xsl:text>
       </xsl:if>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
     </xsl:attribute>
     <xsl:call-template name="mal2html.ui.expander.data"/>
     <div class="inner">
@@ -159,16 +185,30 @@ as well as any special processing for child #{item} elements.
 
 <!-- = terms/item = -->
 <xsl:template match="mal:terms/mal:item">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
   <xsl:for-each select="mal:title">
-    <dt class="terms">
+    <dt>
+      <xsl:attribute name="class">
+        <xsl:text>terms</xsl:text>
+        <xsl:if test="$if != 'true'">
+          <xsl:text> if-if </xsl:text>
+          <xsl:value-of select="$if"/>
+        </xsl:if>
+      </xsl:attribute>
       <xsl:call-template name="html.lang.attrs">
         <xsl:with-param name="parent" select=".."/>
       </xsl:call-template>
       <xsl:apply-templates mode="mal2html.inline.mode"/>
     </dt>
   </xsl:for-each>
-  <dd class="terms">
+  <dd>
+    <xsl:attribute name="class">
+      <xsl:text>terms</xsl:text>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
+    </xsl:attribute>
     <xsl:call-template name="html.lang.attrs"/>
     <xsl:apply-templates mode="mal2html.block.mode" select="*[not(self::mal:title)]"/>
   </dd>
@@ -177,7 +217,7 @@ as well as any special processing for child #{item} elements.
 
 <!-- = tree = -->
 <xsl:template mode="mal2html.block.mode" match="mal:tree">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
   <xsl:variable name="lines" select="contains(concat(' ', @style, ' '), ' lines ')"/>
   <div>
     <xsl:call-template name="html.lang.attrs"/>
@@ -189,6 +229,10 @@ as well as any special processing for child #{item} elements.
       <xsl:if test="mal:title and @ui:expanded">
         <xsl:text> ui-expander</xsl:text>
       </xsl:if>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
     </xsl:attribute>
     <xsl:call-template name="mal2html.ui.expander.data"/>
     <div class="inner">
@@ -235,8 +279,15 @@ neighboring #{item} elements, and passes that prefix to child elements.
       </xsl:otherwise>
     </xsl:choose>
   </xsl:variable>
-  <xsl:if test="$if = 'true'">
-  <li class="tree">
+  <xsl:if test="$if != ''">
+  <li>
+    <xsl:attribute name="class">
+      <xsl:text>tree</xsl:text>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
+    </xsl:attribute>
     <xsl:call-template name="html.lang.attrs"/>
     <div>
       <xsl:if test="$lines">
diff --git a/xslt/mallard/html/mal2html-media.xsl b/xslt/mallard/html/mal2html-media.xsl
index 1100a50..9bacc3a 100644
--- a/xslt/mallard/html/mal2html-media.xsl
+++ b/xslt/mallard/html/mal2html-media.xsl
@@ -144,9 +144,16 @@ FIXME
   <xsl:variable name="if">
     <xsl:call-template name="mal.if.test"/>
   </xsl:variable>
-  <xsl:if test="$if = 'true'">
-    <xsl:apply-templates mode="mal2html.ttml.mode" select="tt:body"/>
-  </xsl:if>
+  <xsl:choose>
+    <xsl:when test="$if = 'true'">
+      <xsl:apply-templates mode="mal2html.ttml.mode" select="tt:body"/>
+    </xsl:when>
+    <xsl:when test="$if != ''">
+      <div class="if-if {$if}">
+        <xsl:apply-templates mode="mal2html.ttml.mode" select="tt:body"/>
+      </div>
+    </xsl:when>
+  </xsl:choose>
 </xsl:template>
 
 <xsl:template mode="mal2html.ttml.mode" match="tt:body">
@@ -312,12 +319,16 @@ FIXME
     </xsl:choose>
   </xsl:variable>
   <xsl:choose>
-    <xsl:when test="$if != 'true'"/>
+    <xsl:when test="$if = ''"/>
     <xsl:when test="@type = 'image' or not(@type)">
       <div>
         <xsl:attribute name="class">
           <xsl:text>media media-image</xsl:text>
           <xsl:value-of select="$class"/>
+          <xsl:if test="$if != 'true'">
+            <xsl:text> if-if </xsl:text>
+            <xsl:value-of select="$if"/>
+          </xsl:if>
         </xsl:attribute>
         <div class="inner">
           <xsl:call-template name="mal2html.media.image"/>
@@ -329,6 +340,10 @@ FIXME
         <xsl:attribute name="class">
           <xsl:text>media media-video</xsl:text>
           <xsl:value-of select="$class"/>
+          <xsl:if test="$if != 'true'">
+            <xsl:text> if-if </xsl:text>
+            <xsl:value-of select="$if"/>
+          </xsl:if>
         </xsl:attribute>
         <div class="inner">
           <xsl:call-template name="mal2html.media.video"/>
@@ -340,6 +355,10 @@ FIXME
         <xsl:attribute name="class">
           <xsl:text>media media-audio</xsl:text>
           <xsl:value-of select="$class"/>
+          <xsl:if test="$if != 'true'">
+            <xsl:text> if-if </xsl:text>
+            <xsl:value-of select="$if"/>
+          </xsl:if>
         </xsl:attribute>
         <div class="inner">
           <xsl:call-template name="mal2html.media.audio"/>
diff --git a/xslt/mallard/html/mal2html-page.xsl b/xslt/mallard/html/mal2html-page.xsl
index 8c3d16d..529e789 100644
--- a/xslt/mallard/html/mal2html-page.xsl
+++ b/xslt/mallard/html/mal2html-page.xsl
@@ -1065,6 +1065,22 @@ span.gloss-desc {
   box-shadow: 2px 2px 4px </xsl:text>
     <xsl:value-of select="$color.gray_border"/><xsl:text>;
 }
+
+.if-if { display: none; }
+.if-choose, .if-when, .if-else { margin: 0; padding: 0; }
+.if-choose > .if-when { display: none; }
+.if-choose > .if-else { display: block; }
+.if-if.if__not-target-mobile { display: block; }
+.if-choose.if__not-target-mobile > .if-when { display: block; }
+.if-choose.if__not-target-mobile > .if-else { display: none; }
+ media only screen and (max-width: 480px) {
+  .if-if.if__target-mobile { display: block; }
+  .if-if.if__not-target-mobile { display: none; }
+  .if-choose.if__target-mobile > .if-when { display: block; }
+  .if-choose.if__target-mobile > .if-else { display: none; }
+  .if-choose.if__not-target-mobile > .if-when { display: none; }
+  .if-choose.if__not-target-mobile > .if-else { display: block; }
+}
 </xsl:text>
 <xsl:if test="$mal2html.editor_mode">
 <xsl:text>
diff --git a/xslt/mallard/html/mal2html-svg.xsl b/xslt/mallard/html/mal2html-svg.xsl
index c40ec79..9bb2e81 100644
--- a/xslt/mallard/html/mal2html-svg.xsl
+++ b/xslt/mallard/html/mal2html-svg.xsl
@@ -85,7 +85,7 @@ certain Mallard extensions, for example to use the Mallard linking mechanism.
 </xsl:template>
 
 <xsl:template mode="mal2html.block.mode" match="svg:svg">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
   <xsl:variable name="id">
     <xsl:choose>
       <xsl:when test="@xml:id">
@@ -101,12 +101,26 @@ certain Mallard extensions, for example to use the Mallard linking mechanism.
   </xsl:variable>
   <xsl:choose>
     <xsl:when test="$html.xhtml">
-      <div class="svg">
+      <div>
+        <xsl:attribute name="class">
+          <xsl:text>svg</xsl:text>
+          <xsl:if test="$if != 'true'">
+            <xsl:text> if-if </xsl:text>
+            <xsl:value-of select="$if"/>
+          </xsl:if>
+        </xsl:attribute>
         <xsl:apply-templates mode="mal2html.svg.mode" select="."/>
       </div>
     </xsl:when>
     <xsl:otherwise>
-      <div class="svg">
+      <div>
+        <xsl:attribute name="class">
+          <xsl:text>svg</xsl:text>
+          <xsl:if test="$if != 'true'">
+            <xsl:text> if-if </xsl:text>
+            <xsl:value-of select="$if"/>
+          </xsl:if>
+        </xsl:attribute>
         <object data="{$id}.svg" type="image/svg+xml">
           <xsl:copy-of select="@width"/>
           <xsl:copy-of select="@height"/>
diff --git a/xslt/mallard/html/mal2html-table.xsl b/xslt/mallard/html/mal2html-table.xsl
index 032ebfa..0aa348e 100644
--- a/xslt/mallard/html/mal2html-table.xsl
+++ b/xslt/mallard/html/mal2html-table.xsl
@@ -35,7 +35,7 @@ REMARK: Describe this module
 
 <!-- = table = -->
 <xsl:template mode="mal2html.block.mode" match="mal:table">
-  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if = 'true'">
+  <xsl:variable name="if"><xsl:call-template name="mal.if.test"/></xsl:variable><xsl:if test="$if != ''">
   <xsl:variable name="cols" select="mal:col | mal:colgroup/mal:col"/>
   <xsl:variable name="style">
     <xsl:if test="@frame and @frame != 'none'">
@@ -173,6 +173,10 @@ REMARK: Describe this module
       <xsl:if test="mal:title and @ui:expanded">
         <xsl:text> ui-expander</xsl:text>
       </xsl:if>
+      <xsl:if test="$if != 'true'">
+        <xsl:text> if-if </xsl:text>
+        <xsl:value-of select="$if"/>
+      </xsl:if>
     </xsl:attribute>
     <xsl:call-template name="mal2html.ui.expander.data"/>
     <div class="inner">
diff --git a/xslt/mallard/html/mal2html.xsl b/xslt/mallard/html/mal2html.xsl
index 401dc0d..a906d8d 100644
--- a/xslt/mallard/html/mal2html.xsl
+++ b/xslt/mallard/html/mal2html.xsl
@@ -27,11 +27,10 @@ Mallard to HTML
 REMARK: Describe this module
 -->
 
-<xsl:include href="mal2xhtml.xsl" pass="true"><?pass?></xsl:include>
-
-<!--#@ html.xhtml -->
 <xsl:param name="html.xhtml" select="false()"/>
-<xsl:param name="mal.if.env" select="'html'"/>
+<xsl:param name="mal.if.target" select="'target:html'"/>
+
+<xsl:include href="mal2xhtml.xsl" pass="true"><?pass?></xsl:include>
 
 <xsl:namespace-alias stylesheet-prefix="html" result-prefix="#default"/>
 
diff --git a/xslt/mallard/html/mal2xhtml.xsl b/xslt/mallard/html/mal2xhtml.xsl
index 5822022..ff78420 100644
--- a/xslt/mallard/html/mal2xhtml.xsl
+++ b/xslt/mallard/html/mal2xhtml.xsl
@@ -39,7 +39,11 @@ REMARK: Describe this module
 <xsl:import href="../common/mal-if.xsl"/>
 <xsl:import href="../common/mal-link.xsl"/>
 
-<xsl:param name="mal.if.env" select="'html xhtml'"/>
+<xsl:param name="mal.if.target" select="'target:html target:xhtml'"/>
+<xsl:param name="mal.if.features" select="'
+mallard:1.0
+'"/>
+<xsl:param name="mal.if.maybe" select="'target:mobile'"/>
 <xsl:param name="mal.link.extension" select="$html.extension"/>
 
 <xsl:include href="mal2html-api.xsl"/>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]