[projectaon] Re: Proposed new CRT

  • From: Ingo Kloecker <projectaon@xxxxxxxxxxxxxxxx>
  • To: projectaon@xxxxxxxxxxxxx
  • Date: Thu, 16 Apr 2009 20:27:43 +0200

On Thursday 16 April 2009, Iain Smith wrote:
> I'm guessing that we wouldn't be interested in generating a table
> directly, rather that we would want to produce XML/XSL which would in
> turn generate the table during the publication process.  If I have
> any time tomorrow I may give this a try.

The XML files do already contain an XML representation of the CRT (or at 
least 01fftd.xml does). I'm using this XML representation already for 
creating a nice CRT in LaTeX (which will eventually result in PDF).
Below is the relevant XSLT code I came up with. Maybe it is useful as 
template for writing the XSLT for producing an HTML table or an SVG.

========================================

<!-- :::::::::::::: combat results table template ::::::::::::::: -->

<xsl:template match="/gamebook/section/data/section[@id='crtable']">

 <xsl:text>\clearpage</xsl:text>
 <xsl:value-of select="$newline" />
 <xsl:text>\ifthispageodd{\thispagestyle{empty}~\clearpage}{}</xsl:text>
 <xsl:value-of select="$newparagraph" />

 <xsl:text>\phantomsection\hypertarget{crtable}{}</xsl:text>
 <xsl:value-of select="$newline" />
 <xsl:text>\addcontentsline{toc}{chapter}{\protect{</xsl:text>
  <xsl:apply-templates select="meta/title[1]" />
 <xsl:text>}}</xsl:text>
 <xsl:value-of select="$newparagraph" />

  <xsl:choose>
    <xsl:when test="data/illustration/instance[@class='text']">
      <xsl:text>\thispagestyle{empty}</xsl:text>
      <xsl:value-of select="$newparagraph" />
      <xsl:call-template name="combat-ratio-table">
        <xsl:with-param name="title">Negative Combat 
Ratio</xsl:with-param>
        <xsl:with-param name="startCol" select="1" />
        <xsl:with-param name="endCol" select="7" />
        <xsl:with-param name="colHeaders">
          <th><xsl:text>\shortstack{\footnotesize \textbf{-11} or\\ 
\footnotesize less}</xsl:text></th>
          <th><xsl:text>\footnotesize \bfseries -10/-9</xsl:text></th>
          <th><xsl:text>\footnotesize \bfseries -8/-7</xsl:text></th>
          <th><xsl:text>\footnotesize \bfseries -6/-5</xsl:text></th>
          <th><xsl:text>\footnotesize \bfseries -4/-3</xsl:text></th>
          <th><xsl:text>\footnotesize \bfseries -2/-1</xsl:text></th>
          <th><xsl:text>\footnotesize \bfseries 0</xsl:text></th>
        </xsl:with-param>
        <xsl:with-param name="showLeftLabel" select="1" />
      </xsl:call-template>
      <xsl:text>\clearpage</xsl:text>
      <xsl:value-of select="$newparagraph" />
      <xsl:text>\thispagestyle{empty}</xsl:text>
      <xsl:value-of select="$newparagraph" />
      <xsl:call-template name="combat-ratio-table">
        <xsl:with-param name="title">Positive Combat 
Ratio</xsl:with-param>
        <xsl:with-param name="startCol" select="7" />
        <xsl:with-param name="endCol" select="13" />
        <xsl:with-param name="colHeaders">
          <th><xsl:text>\footnotesize \bfseries 0</xsl:text></th>
          <th><xsl:text>\footnotesize \bfseries 1/2</xsl:text></th>
          <th><xsl:text>\footnotesize \bfseries 3/4</xsl:text></th>
          <th><xsl:text>\footnotesize \bfseries 5/6</xsl:text></th>
          <th><xsl:text>\footnotesize \bfseries 7/8</xsl:text></th>
          <th><xsl:text>\footnotesize \bfseries 9/10</xsl:text></th>
          <th><xsl:text>\shortstack{\footnotesize \textbf{11} or\\ 
\footnotesize greater}</xsl:text></th>
        </xsl:with-param>
        <xsl:with-param name="showRightLabel" select="1" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:message terminate="yes">
        Error: Instance of random number table of class 'text' is 
missing.
      </xsl:message>
    </xsl:otherwise>
  </xsl:choose>

</xsl:template>

========================================

<!--
        Subroutines to generate the combat ratio tables.
-->

<xsl:template name="combat-ratio-table">
  <xsl:param name="title" />
  <xsl:param name="startCol" />
  <xsl:param name="endCol" />
  <xsl:param name="colHeaders" />
  <xsl:param name="showLeftLabel" select="0" />
  <xsl:param name="showRightLabel" select="0" />

  <xsl:variable name="offsetX">0</xsl:variable>
  <xsl:variable name="offsetY">0</xsl:variable>

  <!-- calculate a few sizes and positions -->
  <xsl:variable name="leftLabelWidth" select="number($showLeftLabel) * 
number($sideLabelWidth)" />
  <xsl:variable name="rightLabelWidth" select="number($showRightLabel) * 
number($sideLabelWidth)" />

  <xsl:variable name="legendWidth" select="2 * number($rnColWidth) + 7 * 
number($resultBoxWidth)" />
  <xsl:variable name="legendX" select="$leftLabelWidth" />
  <xsl:variable name="legendY" select="0" />

  <xsl:variable name="topLabelX" select="number($leftLabelWidth) + 
number($legendWidth) div 2" />
  <xsl:variable name="topLabelY" select="number($legendHeight) + 
number($legendSep) + 2 * number($combatRatioBoxHeight) + 10 * 
number($resultBoxHeight) + number($topLabelSep)" />

  <xsl:variable name="leftLabelX" select="number($leftLabelWidth) div 
2" />
  <xsl:variable name="leftLabelY" select="number($legendHeight) + 
number($legendSep) + number($combatRatioBoxHeight) + 5 * 
number($resultBoxHeight)" />
  <xsl:variable name="rightLabelX" select="number($leftLabelWidth) + 2 * 
number($rnColWidth) + 7 * number($resultBoxWidth) + 
number($rightLabelWidth) div 2" />
  <xsl:variable name="rightLabelY" select="number($legendHeight) + 
number($legendSep) + number($combatRatioBoxHeight) + 5 * 
number($resultBoxHeight)" />

  <xsl:variable name="randomNumberBoxesLeftX" 
select="$leftLabelWidth" />
  <xsl:variable name="randomNumberBoxesRightX" 
select="number($leftLabelWidth) + number($rnColWidth) + 7 * 
number($resultBoxWidth)" />
  <xsl:variable name="randomNumberBoxesY" select="number($legendHeight) 
+ number($legendSep) + number($combatRatioBoxHeight)" />

  <xsl:variable name="resultBoxesX" select="number($leftLabelWidth) + 
number($rnColWidth)" />
  <xsl:variable name="resultBoxesY" select="number($legendHeight) + 
number($legendSep) + number($combatRatioBoxHeight)" />

  <xsl:variable name="combatRatioBoxesX" select="number($leftLabelWidth) 
+ number($rnColWidth)" />
  <xsl:variable name="combatRatioBoxesBottomY" 
select="number($legendHeight) + number($legendSep)" />
  <xsl:variable name="combatRatioBoxesTopY" 
select="number($legendHeight) + number($legendSep) + 
number($combatRatioBoxHeight) + 10 * number($resultBoxHeight)" />

  <xsl:text>\setlength{\unitlength}{1mm}
\noindent\begin{picture}(</xsl:text><xsl:value-of 
select="number($leftLabelWidth) + 2 * number($rnColWidth) + 10 * 
number($resultBoxWidth)" /><xsl:text>,</xsl:text><xsl:value-of 
select="number($legendHeight) + number($legendSep) + 2 * 
number($combatRatioBoxHeight) + 10 * number($resultBoxHeight) + 
number($topLabelSep) + number($topLabelHeight)" /><xsl:text>)
(</xsl:text><xsl:value-of select="-1 * 
number($offsetX)" /><xsl:text>,</xsl:text><xsl:value-of select="-1 * 
number($offsetY)" /><xsl:text>)
  \linethickness{0.25mm}

  %% the legend %%
  \put(</xsl:text><xsl:value-of 
select="$legendX" /><xsl:text>,</xsl:text><xsl:value-of 
select="$legendY" /><xsl:text>){%
    \makebox(</xsl:text><xsl:value-of 
select="$legendWidth" /><xsl:text>,</xsl:text><xsl:value-of 
select="$legendHeight" /><xsl:text>){%
      \mbox{\footnotesize E = Enemy {\scriptsize EP} loss}%
      \hfill%
      \mbox{\footnotesize LW = Lone Wolf {\scriptsize EP} loss}%
      \hfill%
      \mbox{\footnotesize K = Automatic Kill}%
    }%
  }

  %% the labels %%</xsl:text>
  <xsl:value-of select="$newline" />
  <xsl:if test="number($showLeftLabel) = 1">
    <xsl:text>  \put(</xsl:text><xsl:value-of 
select="$leftLabelX" /><xsl:text>,</xsl:text><xsl:value-of 
select="$leftLabelY" /><xsl:text>){\makebox(0,0){\rotatebox{90}
{\bfseries \large Random Number}}}</xsl:text>
    <xsl:value-of select="$newline" />
  </xsl:if>
  <xsl:if test="number($showRightLabel) = 1">
    <xsl:text>  \put(</xsl:text><xsl:value-of 
select="$rightLabelX" /><xsl:text>,</xsl:text><xsl:value-of 
select="$rightLabelY" /><xsl:text>){\makebox(0,0){\rotatebox{270}
{\bfseries \large Random Number}}}</xsl:text>
    <xsl:value-of select="$newline" />
  </xsl:if>
  <xsl:text>  \put(</xsl:text><xsl:value-of 
select="$topLabelX" /><xsl:text>,</xsl:text><xsl:value-of 
select="$topLabelY" /><xsl:text>){\makebox(0,0)[b]{\bfseries \large 
</xsl:text><xsl:value-of select="$title" /><xsl:text>}}

  %% random number boxes %%
  \multiput(</xsl:text><xsl:value-of 
select="$randomNumberBoxesLeftX" /><xsl:text>,</xsl:text><xsl:value-of 
select="$randomNumberBoxesY" /><xsl:text>)(0,</xsl:text><xsl:value-of 
select="2 * number($randomNumberBoxHeight)" /><xsl:text>){5}{%
    \lightgraybox{</xsl:text><xsl:value-of 
select="$randomNumberBoxWidth" /><xsl:text>}{</xsl:text><xsl:value-of 
select="$randomNumberBoxHeight" /><xsl:text>}%
  }
  \multiput(</xsl:text><xsl:value-of 
select="$randomNumberBoxesRightX" /><xsl:text>,</xsl:text><xsl:value-of 
select="$randomNumberBoxesY" /><xsl:text>)(0,</xsl:text><xsl:value-of 
select="2 * number($randomNumberBoxHeight)" /><xsl:text>){5}{%
    \lightgraybox{</xsl:text><xsl:value-of 
select="$randomNumberBoxWidth" /><xsl:text>}{</xsl:text><xsl:value-of 
select="$randomNumberBoxHeight" /><xsl:text>}%
  }

  %% results boxes %%
  \multiput(</xsl:text><xsl:value-of 
select="$resultBoxesX" /><xsl:text>,</xsl:text><xsl:value-of 
select="$resultBoxesY" /><xsl:text>)(0,</xsl:text><xsl:value-of 
select="2 * number($resultBoxHeight)" /><xsl:text>){5}{%
    \multiput(</xsl:text><xsl:value-of 
select="$resultBoxWidth" /><xsl:text>,0)(</xsl:text><xsl:value-of 
select="2 * number($resultBoxWidth)" /><xsl:text>,0){3}{%
      \lightgraybox{</xsl:text><xsl:value-of 
select="$resultBoxWidth" /><xsl:text>}{</xsl:text><xsl:value-of 
select="$resultBoxHeight" /><xsl:text>}%
    }%
  }
  \multiput(</xsl:text><xsl:value-of 
select="$resultBoxesX" /><xsl:text>,</xsl:text><xsl:value-of 
select="number($resultBoxesY) + number($resultBoxHeight)" /><xsl:text>)
(0,</xsl:text><xsl:value-of select="2 * 
number($resultBoxHeight)" /><xsl:text>){5}{%
    \multiput(0,0)(</xsl:text><xsl:value-of select="2 * 
number($resultBoxWidth)" /><xsl:text>,0){4}{%
      \lightgraybox{</xsl:text><xsl:value-of 
select="$resultBoxWidth" /><xsl:text>}{</xsl:text><xsl:value-of 
select="$resultBoxHeight" /><xsl:text>}%
    }%
  }

  %% combat ratio boxes %%
  \multiput(</xsl:text><xsl:value-of select="number($combatRatioBoxesX) 
+ number($combatRatioBoxWidth)" /><xsl:text>,</xsl:text><xsl:value-of 
select="$combatRatioBoxesTopY" /><xsl:text>)(</xsl:text><xsl:value-of 
select="2 * number($combatRatioBoxWidth)" /><xsl:text>,0){3}{%
    \lightgraybox{</xsl:text><xsl:value-of 
select="$combatRatioBoxWidth" /><xsl:text>}{</xsl:text><xsl:value-of 
select="$combatRatioBoxHeight" /><xsl:text>}%
  }
  \multiput(</xsl:text><xsl:value-of 
select="$combatRatioBoxesX" /><xsl:text>,</xsl:text><xsl:value-of 
select="$combatRatioBoxesBottomY" /><xsl:text>)
(</xsl:text><xsl:value-of select="2 * 
number($combatRatioBoxWidth)" /><xsl:text>,0){4}{%
    \lightgraybox{</xsl:text><xsl:value-of 
select="$combatRatioBoxWidth" /><xsl:text>}{</xsl:text><xsl:value-of 
select="$combatRatioBoxHeight" /><xsl:text>}%
  }

  %% lines %%
  \put(</xsl:text><xsl:value-of 
select="$combatRatioBoxesX" /><xsl:text>,</xsl:text><xsl:value-of 
select="$combatRatioBoxesBottomY" /><xsl:text>){%
    \line(1,0){</xsl:text><xsl:value-of select="7 * 
number($combatRatioBoxWidth)" /><xsl:text>}%
  }
  \multiput(</xsl:text><xsl:value-of 
select="$randomNumberBoxesLeftX" /><xsl:text>,</xsl:text><xsl:value-of 
select="$randomNumberBoxesY" /><xsl:text>)(0,</xsl:text><xsl:value-of 
select="$randomNumberBoxHeight" /><xsl:text>){11}{%
    \line(1,0){</xsl:text><xsl:value-of select="2 * 
number($randomNumberBoxWidth) + 7 * 
number($resultBoxWidth)" /><xsl:text>}%
  }
  \multiput(</xsl:text><xsl:value-of 
select="$resultBoxesX" /><xsl:text>,</xsl:text><xsl:value-of 
select="number($resultBoxesY) + number($resultBoxHeight) div 
2" /><xsl:text>)(0,</xsl:text><xsl:value-of 
select="$resultBoxHeight" /><xsl:text>){10}{%
    \line(1,0){</xsl:text><xsl:value-of select="7 * 
number($resultBoxWidth)" /><xsl:text>}%
  }
  \put(</xsl:text><xsl:value-of 
select="$combatRatioBoxesX" /><xsl:text>,</xsl:text><xsl:value-of 
select="number($combatRatioBoxesTopY) + 
number($combatRatioBoxHeight)" /><xsl:text>){%
    \line(1,0){</xsl:text><xsl:value-of select="7 * 
number($combatRatioBoxWidth)" /><xsl:text>}%
  }

  \put(</xsl:text><xsl:value-of 
select="$randomNumberBoxesLeftX" /><xsl:text>,</xsl:text><xsl:value-of 
select="$randomNumberBoxesY" /><xsl:text>){%
    \line(0,1){</xsl:text><xsl:value-of select="10 * 
number($randomNumberBoxHeight)" /><xsl:text>}%
  }
  \multiput(</xsl:text><xsl:value-of 
select="$combatRatioBoxesX" /><xsl:text>,</xsl:text><xsl:value-of 
select="$combatRatioBoxesBottomY" /><xsl:text>)
(</xsl:text><xsl:value-of select="$combatRatioBoxWidth" /><xsl:text>,0)
{8}{%
    \line(0,1){</xsl:text><xsl:value-of select="2 * 
number($combatRatioBoxHeight) + 10 * 
number($randomNumberBoxHeight)" /><xsl:text>}%
  }
  \put(</xsl:text><xsl:value-of select="number($randomNumberBoxesRightX) 
+ number($randomNumberBoxWidth)" /><xsl:text>,</xsl:text><xsl:value-of 
select="$randomNumberBoxesY" /><xsl:text>){%
    \line(0,1){</xsl:text><xsl:value-of select="10 * 
number($randomNumberBoxHeight)" /><xsl:text>}%
  }</xsl:text>
  <xsl:value-of select="$newparagraph" />

  <xsl:text>  %% random numbers %%</xsl:text>
  <xsl:value-of select="$newline" />
  <!-- xsltproc does not understand select="1 to 10"; so we abuse the 
fact that the
       <tbody> element contains more than 10 <tr> elements. -->
  <xsl:for-each 
select="data/illustration/instance[@class='text']/table/tbody/tr">
    <xsl:if test="position() &lt; 11">
      <xsl:text>  \multiput(</xsl:text><xsl:value-of 
select="number($randomNumberBoxesLeftX) + number($randomNumberBoxWidth) 
div 2" /><xsl:text>,</xsl:text><xsl:value-of 
select="number($randomNumberBoxesY) + ( 10.5 - position() ) * 
number($randomNumberBoxHeight)" /><xsl:text>)(</xsl:text><xsl:value-of 
select="number($randomNumberBoxWidth) + 7 * 
number($resultBoxWidth)" /><xsl:text>,0){2}{\makebox(0,0){\bfseries 
</xsl:text><xsl:value-of select="position() mod 
10" /><xsl:text>}}</xsl:text>
      <xsl:value-of select="$newline" />
    </xsl:if>
  </xsl:for-each>
  <xsl:value-of select="$newline" />

  <xsl:text>  %% combat ratios %%</xsl:text>
  <xsl:value-of select="$newline" />
  <xsl:for-each select="exslt:node-set($colHeaders)/*">
    <xsl:text>  \multiput(</xsl:text><xsl:value-of 
select="number($combatRatioBoxesX) + ( position() - 0.5 ) * 
number($combatRatioBoxWidth)" /><xsl:text>,</xsl:text><xsl:value-of 
select="number($combatRatioBoxesBottomY) + 
number($combatRatioBoxHeight) div 2" /><xsl:text>)
(0,</xsl:text><xsl:value-of select="10 * number($resultBoxHeight) + 
number($combatRatioBoxHeight)" /><xsl:text>){2}{%</xsl:text>
    <xsl:value-of select="$newline" />
    <xsl:text>    \makebox(0,0){</xsl:text><xsl:value-of 
select="." /><xsl:text>}%</xsl:text>
    <xsl:value-of select="$newline" />
    <xsl:text>  }</xsl:text>
    <xsl:value-of select="$newline" />
  </xsl:for-each>
  <xsl:value-of select="$newline" />

  <xsl:text>  %% E &amp; LW %%</xsl:text>
  <xsl:value-of select="$newline" />
  <xsl:text>  \multiput(</xsl:text><xsl:value-of 
select="$resultBoxesX" /><xsl:text>,</xsl:text><xsl:value-of 
select="$resultBoxesY" /><xsl:text>)(0,</xsl:text><xsl:value-of 
select="$resultBoxHeight" /><xsl:text>){10}{%
    \multiput(0,0)(</xsl:text><xsl:value-of 
select="$resultBoxWidth" /><xsl:text>,0){7}{%
      \makebox(0,</xsl:text><xsl:value-of 
select="number($resultBoxHeight) div 2" /><xsl:text>)[l]{\footnotesize 
~LW}%
    }%
  }
  \multiput(</xsl:text><xsl:value-of 
select="$resultBoxesX" /><xsl:text>,</xsl:text><xsl:value-of 
select="number($resultBoxesY) + number($resultBoxHeight) div 
2" /><xsl:text>)(0,</xsl:text><xsl:value-of 
select="$resultBoxHeight" /><xsl:text>){10}{%
    \multiput(0,0)(</xsl:text><xsl:value-of 
select="$resultBoxWidth" /><xsl:text>,0){7}{%
      \makebox(0,</xsl:text><xsl:value-of 
select="number($resultBoxHeight) div 2" /><xsl:text>)[l]{\footnotesize 
~E}%
    }%
  }</xsl:text>
  <xsl:value-of select="$newparagraph" />

  <xsl:text>  %% losses %%</xsl:text>
  <xsl:value-of select="$newline" />
  <xsl:for-each 
select="data/illustration/instance[@class='text']/table/tbody/tr">
    <!-- the actual data is in row 3..12 -->
    <xsl:variable name="row" select="position() - 2" />
    <xsl:for-each select="./td">
      <xsl:if test="position() = 1">
        <xsl:text>  %% row </xsl:text><xsl:value-of 
select="$row" /><xsl:text> %%</xsl:text>
        <xsl:value-of select="$newline" />
      </xsl:if>
      <xsl:if test="position() &gt;= number($startCol) and position() 
&lt;= number($endCol)">
        <xsl:variable name="col" select="position() - number($startCol) 
+ 1" />
        <xsl:variable name="losses"><xsl:value-of 
select="." /></xsl:variable>
        <xsl:variable name="lossE" 
select="substring-before($losses,'/')" />
        <xsl:text>  \put(</xsl:text><xsl:value-of 
select="number($resultBoxesX) + number($col) * 
number($resultBoxWidth)" /><xsl:text>,</xsl:text><xsl:value-of 
select="number($resultBoxesY) + ( 10.5 - number($row) ) * 
number($resultBoxHeight)" /><xsl:text>)
{\makebox(0,</xsl:text><xsl:value-of select="number($resultBoxHeight) 
div 2" /><xsl:text>)[r]{\footnotesize </xsl:text>
        <xsl:choose>
          <xsl:when test="$lossE='k'">
            <xsl:text>K</xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$lossE" />
          </xsl:otherwise>
        </xsl:choose>
        <xsl:text>~}}</xsl:text>
        <xsl:value-of select="$newline" />
        <xsl:variable name="lossLW" 
select="substring-after($losses,'/')" />
        <xsl:text>  \put(</xsl:text><xsl:value-of 
select="number($resultBoxesX) + number($col) * 
number($resultBoxWidth)" /><xsl:text>,</xsl:text><xsl:value-of 
select="number($resultBoxesY) + ( 10 - number($row) ) * 
number($resultBoxHeight)" /><xsl:text>)
{\makebox(0,</xsl:text><xsl:value-of select="number($resultBoxHeight) 
div 2" /><xsl:text>)[r]{\footnotesize </xsl:text>
        <xsl:choose>
          <xsl:when test="$lossLW='k'">
            <xsl:text>K</xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$lossLW" />
          </xsl:otherwise>
        </xsl:choose>
        <xsl:text>~}}</xsl:text>
        <xsl:value-of select="$newline" />
      </xsl:if>
    </xsl:for-each>
  </xsl:for-each>

  <xsl:text>\end{picture}</xsl:text>
  <xsl:value-of select="$newline" />
  <xsl:text>\setlength{\unitlength}{1pt}</xsl:text>
  <xsl:value-of select="$newparagraph" />

</xsl:template>

========================================

Regards,
Ingo

~~~~~~
Manage your subscription at http://www.freelists.org/list/projectaon


Other related posts: