<?xml version="1.0"?>
<!--
  Copyright (C) 2014-2023 Ryan Specialty, LLC.

  This file is part of tame-core.

  tame-core is free software: you can redistribute it and/or modify it
  under the terms of the GNU General Public License as
  published by the Free Software Foundation, either version 3 of the
  License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-->
<package xmlns="http://www.lovullo.com/rater"
         xmlns:c="http://www.lovullo.com/calc"
         xmlns:t="http://www.lovullo.com/rater/apply-template"
         core="true"
         desc="Template Generation">


  This package provides various templates for generating templates and
    iterating using templates.
  In essense,
    this package is intended to abstract away certain implementation details
    and complexities that make groking code more difficult;
      they should be used when possible to improve code maintenance.


  <section title="Iteration">
    \ref{_for-each-n_} recurisvely produces the body~\tt{@values@} given a
      numeric range and step.
    This can also be used to generate sequences at compile-time rather than
      using functions,
        provided that the sequence data are static.

    <template name="_for-each-n_"
              desc="Recursively apply body with counter and step">
      <param name="@values@" desc="Body" />
      <param name="@start@"  desc="Counter start" />
      <param name="@end@"    desc="Counter end" />
      <param name="@step@"   desc="Counter step" />


      <param name="@next_n@" desc="Next iteration value">
        <param-add name="@start@" value="@step@" />
      </param>

      <param name="@n_dec@" desc="Current n - 1">
        <param-add name="@start@" value="-1" />
      </param>


      <!-- inefficient trick to expose @current_n@ to the body -->
      <inline-template>
        <for-each>
          <set current_n="@start@" current_n_dec="@n_dec@" />
        </for-each>

        <param-copy name="@values@" />
      </inline-template>


      <!-- repeat body for each step, as sibling -->
      <unless name="@start@" eq="@end@">
        <t:for-each-n start="@next_n@" end="@end@" step="@step@">
          <param-copy name="@values@" />
        </t:for-each-n>
      </unless>
    </template>
  </section>
</package>
