[DEV-7198] Replace `rate-each` macro with a template

Replacing the existing macros with templates will allow us to now have
to deal with macros in the new compiler.

The `indexNameType` pattern needed to change to allow for variables. I
also had to remove the prefix for the `gentle-no` option of `rate`.
master
Joseph Frazer 2020-04-13 18:58:49 -04:00
parent aa2bc6eedf
commit 15f5867508
4 changed files with 65 additions and 114 deletions

View File

@ -225,5 +225,60 @@
<param-copy name="@values@" />
</rate>
</template>
<template name="_rate-each_"
desc="Convenience template that expands to a lv:rate block summing over
the magic _CMATCH_ set with the product of its value">
<param name="@values@"
desc="Yield calculation" />
<param name="@generates@" desc="Generator name (optional)">
<text></text>
</param>
<param name="@yields@" desc="Yield (optional)">
<text>_</text>
<param-value name="@generates@" />
</param>
<!-- at least one of generates or yields is required -->
<if name="@yields@" eq="">
<if name="@generates@" eq="">
<error>must provide at least one of @generates or @yields</error>
</if>
</if>
<param name="@class@"
desc="Space-delimited classifications for predicated iteration" />
<param name="@no@"
desc="Space-delimited classifications for predicated iteration to prevent matches">
<text></text>
</param>
<param name="@index@"
desc="Generator index" />
<param name="@dim@" desc="Dim (optional)">
<text></text>
</param>
<param name="@gensym@" desc="Generator TeX symbol">
<text></text>
</param>
<rate class="@class@" no="@no@" yields="@yields@"
gentle-no="true"
desc="Total {@yields@} premium">
<c:sum of="_CMATCH_" dim="@dim@" sym="@gensym@"
generates="@generates@" index="@index@"
desc="Set of individual {@yields@} premiums">
<c:product>
<c:value-of name="_CMATCH_" index="@index@"
label="One if {@class@} and not {@no@} (if provided), otherwise zero" />
<param-copy name="@values@" />
</c:product>
</c:sum>
</rate>
</template>
</package>

View File

@ -88,8 +88,8 @@
</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:NCName">
<xs:pattern value="[a-z]" />
<xs:restriction base="xs:string">
<xs:pattern value="[a-z]|\{?@[a-z][a-zA-Z0-9_]*@\}?" />
</xs:restriction>
</xs:simpleType>

View File

@ -1137,7 +1137,7 @@
<variable name="rate" select="." />
<!-- Generate expression for class list (leave the @no check to the cmatch
algorithm, since we want per-index @no's). If @preproc:gentle-no is
algorithm, since we want per-index @no's). If @gentle-no is
set by rate-each expansion, then we want to ignore them entirely,
since we do not want it to clear our the final yield (generators take
care of this using _CMATCH_). -->
@ -1145,7 +1145,7 @@
<variable name="class-set"
select="./lv:class[
( @no = 'true'
and not( $rate/@preproc:gentle-no = 'true' ) )
and not( $rate/@gentle-no = 'true' ) )
or not( @no = 'true' ) ]" />
<choose>

View File

@ -358,119 +358,15 @@
</t:yield>
</template>
<!-- this situation may occur both manually and from lv:rate-each-template -->
<template match="lv:rate-each[ lv:apply-template ]" mode="preproc:macros" priority="9">
<variable name="apply">
<preproc:apply>
<apply-templates select="lv:apply-template" mode="preproc:macros" />
</preproc:apply>
</variable>
<choose>
<!-- did the template apply? (note that we only check for a single one,
since that's all that we should have) -->
<when test="$apply/preproc:apply/lv:apply-template">
<sequence select="." />
<message>
<text>[preproc] waiting to expand rate-each </text>
<value-of select="@yields" />
<text> (immediate template(s) need expansion)...</text>
</message>
</when>
<otherwise>
<!-- it applied! -->
<copy>
<sequence select="@*, *[ not( local-name()='apply-template' ) ]" />
<sequence select="$apply/preproc:apply/*" />
</copy>
<!-- we'll process this block next time around -->
<preproc:repass src="lv:rate-each lv:apply-template" />
</otherwise>
</choose>
</template>
<!--
Convenience macro that expands to a lv:rate block summing over the magic
_CMATCH_ set with the product of its value
The intent here is to reduce highly repetitive code.
wrapper around `<t:rate-each />`
-->
<template match="lv:rate-each" mode="preproc:macros" priority="5">
<!-- TODO: debug flag
<message>
<text>[preproc] expanding rate-each </text>
<value-of select="@yields" />
<text>...</text>
</message>
-->
<lv:rate preproc:gentle-no="true">
<sequence select="@*[
not( local-name() = 'index' )
and not( local-name() = 'generates' )
]" />
<if test="not( @yields )">
<!-- if @generates is not supplied either, then we cannot continue -->
<choose>
<when test="not( @generates )">
<!-- TODO: some means of identifying this...the error isn't terribly
helpful... :x -->
<preproc:error>
<text>rate-each must provide either @yields or @generates</text>
</preproc:error>
</when>
<otherwise>
<attribute name="yields"
select="concat( '_', @generates )" />
<attribute name="preproc:yields-generated"
select="'true'" />
</otherwise>
</choose>
</if>
<sequence select="./lv:class" />
<c:sum of="_CMATCH_" index="{@index}" sym="{@gensym}">
<if test="@dim">
<copy-of select="@dim" />
</if>
<!-- copy @generates, if it exists (has the benefit of copying nothing
if it does not exist) -->
<sequence select="@generates" />
<attribute name="desc">
<text>Set of individual </text>
<value-of select="@yields" />
<text> premiums</text>
</attribute>
<c:product>
<c:value-of name="_CMATCH_" index="{@index}">
<attribute name="label">
<text>Zero if not </text>
<value-of select="@class" />
<text>, otherwise one</text>
</attribute>
</c:value-of>
<apply-templates
select="*[
not(
local-name() = 'class'
)
]"
mode="preproc:macros" />
</c:product>
</c:sum>
</lv:rate>
<t:rate-each>
<copy-of select="@*" />
<apply-templates mode="preproc:expand"
select="*[ not( local-name() = 'class' ) ]" />
</t:rate-each>
</template>
</stylesheet>