Deploying to gh-pages from @ edd776beac 🚀

This commit is contained in:
Lemmih 2020-10-08 07:40:21 +00:00
commit fb19f555bb
10 changed files with 676 additions and 513 deletions

View file

@ -7,8 +7,8 @@
100% ( 29 / 29) in 'Reanimate.Math.Common'
100% ( 25 / 25) in 'Reanimate.PolyShape'
100% ( 22 / 22) in 'Reanimate.Effect'
100% ( 21 / 21) in 'Reanimate.LaTeX'
100% ( 19 / 19) in 'Reanimate.Svg'
100% ( 18 / 18) in 'Reanimate.LaTeX'
100% ( 17 / 17) in 'Reanimate.Parameters'
100% ( 14 / 14) in 'Reanimate.Raster'
100% ( 13 / 13) in 'Reanimate.Render'
@ -27,7 +27,7 @@
100% ( 6 / 6) in 'Reanimate.ColorSpace'
100% ( 6 / 6) in 'Reanimate.Builtin.Images'
100% ( 5 / 5) in 'Reanimate.Transform'
100% ( 4 / 4) in 'Reanimate.Svg.Unuse'
100% ( 5 / 5) in 'Reanimate.Svg.Unuse'
100% ( 4 / 4) in 'Reanimate.Svg.BoundingBox'
100% ( 4 / 4) in 'Reanimate.Morph.Rotational'
100% ( 4 / 4) in 'Reanimate.Debug'
@ -37,4 +37,4 @@
100% ( 3 / 3) in 'Reanimate.Math.Balloon'
100% ( 3 / 3) in 'Reanimate.Blender'
100% ( 2 / 2) in 'Reanimate.Builtin.CirclePlot'
80% ( 4 / 5) in 'Reanimate.External'
78% ( 7 / 9) in 'Reanimate.External'

View file

@ -62,10 +62,10 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td align="right">52%</td><td>9/17</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="52%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">66%</td><td>4/6</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="66%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">53%</td><td>67/125</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="53%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.External.hs.html">reanimate-1.1.0.0-inplace/Reanimate.External</a></tt></td>
<td align="right">0%</td><td>0/6</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/5</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/129</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
<td align="right">0%</td><td>0/12</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/26</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/329</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.LaTeX.hs.html">reanimate-1.1.0.0-inplace/Reanimate.LaTeX</a></tt></td>
<td align="right">9%</td><td>4/43</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="9%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">5%</td><td>1/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">4%</td><td>12/292</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="4%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<td align="right">8%</td><td>4/46</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="8%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">5%</td><td>1/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">3%</td><td>12/310</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="3%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Math.Common.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Math.Common</a></tt></td>
<td align="right">0%</td><td>0/26</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/12</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/407</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
@ -125,7 +125,7 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td align="right">80%</td><td>12/15</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="80%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">58%</td><td>43/74</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="58%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">70%</td><td>659/937</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="70%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Svg.Unuse.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Svg.Unuse</a></tt></td>
<td align="right">33%</td><td>1/3</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="33%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/16</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">19%</td><td>28/147</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="19%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<td align="right">25%</td><td>1/4</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="25%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">14%</td><td>28/193</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="14%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Transform.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Transform</a></tt></td>
<td align="right">83%</td><td>5/6</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="83%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">33%</td><td>4/12</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="33%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">45%</td><td>76/166</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="45%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
@ -134,5 +134,5 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td align="right">100%</td><td>6/6</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">50%</td><td>1/2</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="50%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">95%</td><td>43/45</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="95%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr></tr><tr style="background: #e0e0e0">
<th align=left>&nbsp;&nbsp;Program Coverage Total</tt></th>
<td align="right">33%</td><td>261/778</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="33%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">16%</td><td>144/863</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="16%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">31%</td><td>4837/15262</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="31%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<td align="right">33%</td><td>261/788</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="33%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">16%</td><td>144/886</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="16%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">31%</td><td>4837/15526</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="31%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
</table></body></html>

View file

@ -62,7 +62,7 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td align="right">19%</td><td>20/101</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="19%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">5%</td><td>2/36</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">27%</td><td>97/347</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="27%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.LaTeX.hs.html">reanimate-1.1.0.0-inplace/Reanimate.LaTeX</a></tt></td>
<td align="right">9%</td><td>4/43</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="9%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">5%</td><td>1/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">4%</td><td>12/292</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="4%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<td align="right">8%</td><td>4/46</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="8%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">5%</td><td>1/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">3%</td><td>12/310</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="3%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Math.Polygon.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Math.Polygon</a></tt></td>
<td align="right">9%</td><td>8/82</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="9%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">5%</td><td>4/75</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">2%</td><td>59/2409</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="2%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
@ -86,7 +86,7 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td align="right">0%</td><td>0/17</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/30</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/625</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.External.hs.html">reanimate-1.1.0.0-inplace/Reanimate.External</a></tt></td>
<td align="right">0%</td><td>0/6</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/5</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/129</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
<td align="right">0%</td><td>0/12</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/26</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/329</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Math.Common.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Math.Common</a></tt></td>
<td align="right">0%</td><td>0/26</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/12</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/407</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
@ -107,7 +107,7 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td align="right">5%</td><td>1/19</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/53</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">4%</td><td>39/852</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="4%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Svg.Unuse.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Svg.Unuse</a></tt></td>
<td align="right">33%</td><td>1/3</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="33%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/16</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">19%</td><td>28/147</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="19%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<td align="right">25%</td><td>1/4</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="25%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">14%</td><td>28/193</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="14%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Paths_reanimate.hs.html">reanimate-1.1.0.0-inplace/Paths_reanimate</a></tt></td>
<td align="right">20%</td><td>3/15</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="20%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">-&nbsp;</td><td>0/0</td><td width=100>&nbsp;</td><td align="right">20%</td><td>12/58</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="20%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
@ -134,5 +134,5 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td align="right">66%</td><td>12/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="66%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">-&nbsp;</td><td>0/0</td><td width=100>&nbsp;</td><td align="right">72%</td><td>172/236</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="72%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr></tr><tr style="background: #e0e0e0">
<th align=left>&nbsp;&nbsp;Program Coverage Total</tt></th>
<td align="right">33%</td><td>261/778</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="33%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">16%</td><td>144/863</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="16%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">31%</td><td>4837/15262</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="31%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<td align="right">33%</td><td>261/788</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="33%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">16%</td><td>144/886</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="16%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">31%</td><td>4837/15526</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="31%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
</table></body></html>

View file

@ -70,9 +70,6 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Paths_reanimate.hs.html">reanimate-1.1.0.0-inplace/Paths_reanimate</a></tt></td>
<td align="right">20%</td><td>3/15</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="20%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">-&nbsp;</td><td>0/0</td><td width=100>&nbsp;</td><td align="right">20%</td><td>12/58</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="20%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Svg.Unuse.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Svg.Unuse</a></tt></td>
<td align="right">33%</td><td>1/3</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="33%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/16</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">19%</td><td>28/147</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="19%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.PolyShape.hs.html">reanimate-1.1.0.0-inplace/Reanimate.PolyShape</a></tt></td>
<td align="right">22%</td><td>8/35</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="22%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">27%</td><td>13/48</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="27%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">18%</td><td>127/691</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="18%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
@ -82,21 +79,24 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Parameters.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Parameters</a></tt></td>
<td align="right">15%</td><td>3/20</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="15%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">-&nbsp;</td><td>0/0</td><td width=100>&nbsp;</td><td align="right">14%</td><td>7/49</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="14%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Svg.Unuse.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Svg.Unuse</a></tt></td>
<td align="right">25%</td><td>1/4</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="25%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">14%</td><td>28/193</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="14%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Raster.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Raster</a></tt></td>
<td align="right">15%</td><td>2/13</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="15%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/17</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">11%</td><td>52/438</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="11%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Driver.CLI.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Driver.CLI</a></tt></td>
<td align="right">13%</td><td>5/36</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="13%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/65</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">7%</td><td>31/388</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="7%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.LaTeX.hs.html">reanimate-1.1.0.0-inplace/Reanimate.LaTeX</a></tt></td>
<td align="right">9%</td><td>4/43</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="9%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">5%</td><td>1/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">4%</td><td>12/292</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="4%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Render.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Render</a></tt></td>
<td align="right">5%</td><td>1/19</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/53</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">4%</td><td>39/852</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="4%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Driver.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Driver</a></tt></td>
<td align="right">8%</td><td>1/12</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="8%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">1%</td><td>1/55</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="1%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">3%</td><td>9/245</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="3%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.LaTeX.hs.html">reanimate-1.1.0.0-inplace/Reanimate.LaTeX</a></tt></td>
<td align="right">8%</td><td>4/46</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="8%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">5%</td><td>1/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">3%</td><td>12/310</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="3%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Math.Polygon.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Math.Polygon</a></tt></td>
<td align="right">9%</td><td>8/82</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="9%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">5%</td><td>4/75</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">2%</td><td>59/2409</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="2%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
@ -116,7 +116,7 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td align="right">0%</td><td>0/17</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/30</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/625</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.External.hs.html">reanimate-1.1.0.0-inplace/Reanimate.External</a></tt></td>
<td align="right">0%</td><td>0/6</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/5</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/129</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
<td align="right">0%</td><td>0/12</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/26</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/329</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Math.Common.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Math.Common</a></tt></td>
<td align="right">0%</td><td>0/26</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/12</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/407</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
@ -134,5 +134,5 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td align="right">0%</td><td>0/1</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/4</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/56</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
<tr></tr><tr style="background: #e0e0e0">
<th align=left>&nbsp;&nbsp;Program Coverage Total</tt></th>
<td align="right">33%</td><td>261/778</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="33%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">16%</td><td>144/863</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="16%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">31%</td><td>4837/15262</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="31%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<td align="right">33%</td><td>261/788</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="33%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">16%</td><td>144/886</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="16%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">31%</td><td>4837/15526</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="31%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
</table></body></html>

View file

@ -68,7 +68,7 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td align="right">33%</td><td>5/15</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="33%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">17%</td><td>4/23</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="17%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">41%</td><td>138/329</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="41%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Svg.Unuse.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Svg.Unuse</a></tt></td>
<td align="right">33%</td><td>1/3</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="33%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/16</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">19%</td><td>28/147</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="19%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<td align="right">25%</td><td>1/4</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="25%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">14%</td><td>28/193</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="14%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.PolyShape.hs.html">reanimate-1.1.0.0-inplace/Reanimate.PolyShape</a></tt></td>
<td align="right">22%</td><td>8/35</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="22%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">27%</td><td>13/48</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="27%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">18%</td><td>127/691</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="18%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
@ -88,15 +88,15 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Driver.CLI.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Driver.CLI</a></tt></td>
<td align="right">13%</td><td>5/36</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="13%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/65</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">7%</td><td>31/388</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="7%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.LaTeX.hs.html">reanimate-1.1.0.0-inplace/Reanimate.LaTeX</a></tt></td>
<td align="right">9%</td><td>4/43</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="9%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">5%</td><td>1/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">4%</td><td>12/292</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="4%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Math.Polygon.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Math.Polygon</a></tt></td>
<td align="right">9%</td><td>8/82</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="9%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">5%</td><td>4/75</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">2%</td><td>59/2409</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="2%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Driver.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Driver</a></tt></td>
<td align="right">8%</td><td>1/12</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="8%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">1%</td><td>1/55</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="1%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">3%</td><td>9/245</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="3%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.LaTeX.hs.html">reanimate-1.1.0.0-inplace/Reanimate.LaTeX</a></tt></td>
<td align="right">8%</td><td>4/46</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="8%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">5%</td><td>1/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">3%</td><td>12/310</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="3%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Render.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Render</a></tt></td>
<td align="right">5%</td><td>1/19</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="5%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/53</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">4%</td><td>39/852</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="4%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<tr>
@ -116,7 +116,7 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td align="right">0%</td><td>0/17</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/30</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/625</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.External.hs.html">reanimate-1.1.0.0-inplace/Reanimate.External</a></tt></td>
<td align="right">0%</td><td>0/6</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/5</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/129</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
<td align="right">0%</td><td>0/12</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/26</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/329</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
<tr>
<td>&nbsp;&nbsp;<tt>module <a href="reanimate-1.1.0.0-inplace/Reanimate.Math.Common.hs.html">reanimate-1.1.0.0-inplace/Reanimate.Math.Common</a></tt></td>
<td align="right">0%</td><td>0/26</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/12</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/407</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
@ -134,5 +134,5 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }
<td align="right">0%</td><td>0/1</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/4</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td><td align="right">0%</td><td>0/56</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 class="invbar"></td></tr></table></td></tr></table></td></tr>
<tr></tr><tr style="background: #e0e0e0">
<th align=left>&nbsp;&nbsp;Program Coverage Total</tt></th>
<td align="right">33%</td><td>261/778</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="33%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">16%</td><td>144/863</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="16%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">31%</td><td>4837/15262</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="31%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
<td align="right">33%</td><td>261/788</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="33%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">16%</td><td>144/886</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="16%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td><td align="right">31%</td><td>4837/15526</td><td width=100><table cellpadding=0 cellspacing=0 width="100" class="bar"><tr><td><table cellpadding=0 cellspacing=0 width="31%"><tr><td height=12 class="bar"></td></tr></table></td></tr></table></td></tr>
</table></body></html>

View file

@ -10,4 +10,4 @@ const snippets = [{"title": "Hello World","url": "https://reanimate.clozecards.c
,{"title": "Camera","url": "https://reanimate.clozecards.com/JlWlOpJvDds/150.svg","code": "animation :: Animation\nanimation = docEnv $ mapA (withFillOpacity 1) $ scene $ do\n cam <- newObject Camera\n\n txt <- newObject $ center $ latex \"Fixed (non-cam)\"\n oModifyS txt $ do\n oTopY .= screenTop \n oZIndex .= 2\n\n circle <- newObject $ withFillColor \"blue\" $ mkCircle 1\n cameraAttach cam circle\n circleRight <- oRead circle oRightX\n\n box <- newObject $ withFillColor \"green\" $ mkRect 2 2\n cameraAttach cam box\n oModify box $ oLeftX .~ circleRight\n boxCenter <- oRead box oCenterXY\n\n small <- newObject $ center $ latex \"This text is very small\"\n cameraAttach cam small\n oModifyS small $ do\n oCenterXY .= boxCenter\n oScale .= 0.1\n \n oShow txt\n oShow small\n oShow circle\n oShow box\n\n wait 1\n\n cameraFocus cam boxCenter\n waitOn $ do\n fork $ cameraPan cam 3 boxCenter\n fork $ cameraZoom cam 3 15\n \n wait 2\n cameraZoom cam 3 1\n cameraPan cam 1 (V2 0 0)\n"}
,{"title": "Fonts","url": "https://reanimate.clozecards.com/OYwvpm$1aI3/180.svg","code": "fonts :: [(T.Text, TexConfig)]\nfonts =\n [ (\"Computer Modern\", defaultCfg)\n , (\"Calligra\", calligra)\n , (\"Noto\", noto)\n , (\"Helvetica\", helvet)\n , (\"Liberine\", libertine)\n , (\"Chalkduster\", chalkduster) ]\n\nanimation :: Animation\nanimation = env $\n scene $ do\n forM_ fonts $ \\(name, cfg) -> do\n play $ showCfg name cfg\n & setDuration 2\n & applyE (overBeginning 0.3 fadeInE)\n & applyE (overEnding 0.3 fadeOutE)\n\ndefaultCfg = TexConfig LaTeX [] []\n\nshowCfg :: T.Text -> TexConfig -> Animation\nshowCfg name cfg = scene $ do\n let title = scale 2 $ center $\n latexCfg cfg name\n line1 = center $ latexCfg cfg\n \"Pack My Box\"\n line2 = center $ latexCfg cfg\n \"With Five Dozen\"\n line3 = center $ latexCfg cfg\n \"Liquour Jugs\"\n\n header <- oNew title\n oModify header $\n oTopY .~ screenTop\n oShow header\n\n l1 <- oNew line1\n l1 `oBelow` header\n oShow l1\n\n l2 <- oNew line2\n l2 `oBelow` l1\n oShow l2\n\n l3 <- oNew line3\n l3 `oBelow` l2\n oShow l3\n wait 1\n\noBelow a b = do\n aBot <- oRead b oBottomY\n oModifyS a $ do\n oMarginTop .= 0\n oTopY .= aBot\n\nenv =\n addStatic (mkBackground \"white\") .\n mapA (withStrokeWidth 0)\n\n"}
];
const playgroundVersion = "2020-10-07 (5ec3e)";
const playgroundVersion = "2020-10-08 (edd77)";

View file

@ -22,96 +22,205 @@ span.spaces { background: white }
<span class="lineno"> 3 </span> SHA256,
<span class="lineno"> 4 </span> zipArchive,
<span class="lineno"> 5 </span> tarball,
<span class="lineno"> 6 </span> )
<span class="lineno"> 7 </span>where
<span class="lineno"> 8 </span>
<span class="lineno"> 9 </span>import Control.Monad (unless)
<span class="lineno"> 10 </span>import Crypto.Hash.SHA256 (hash)
<span class="lineno"> 11 </span>import qualified Data.ByteString as B (readFile)
<span class="lineno"> 12 </span>import Data.ByteString.Base64 (encode)
<span class="lineno"> 13 </span>import qualified Data.ByteString.Char8 as B8 (unpack)
<span class="lineno"> 14 </span>import Reanimate.Misc (getReanimateCacheDirectory, withTempFile)
<span class="lineno"> 15 </span>import System.Directory (doesDirectoryExist, findExecutable)
<span class="lineno"> 16 </span>import System.FilePath ((&lt;/&gt;))
<span class="lineno"> 17 </span>import System.IO.Unsafe (unsafePerformIO)
<span class="lineno"> 18 </span>import System.Process (callProcess)
<span class="lineno"> 19 </span>
<span class="lineno"> 20 </span>-- | Resource address
<span class="lineno"> 21 </span>type URL = String
<span class="lineno"> 22 </span>
<span class="lineno"> 23 </span>-- | Resource hash
<span class="lineno"> 24 </span>type SHA256 = String
<span class="lineno"> 25 </span>
<span class="lineno"> 26 </span>fetchStaticFile :: URL -&gt; SHA256 -&gt; (FilePath -&gt; FilePath -&gt; IO ()) -&gt; IO FilePath
<span class="lineno"> 27 </span><span class="decl"><span class="nottickedoff">fetchStaticFile url sha256 unpack = do</span>
<span class="lineno"> 28 </span><span class="spaces"> </span><span class="nottickedoff">root &lt;- getReanimateCacheDirectory</span>
<span class="lineno"> 29 </span><span class="spaces"> </span><span class="nottickedoff">let folder = root &lt;/&gt; sha256</span>
<span class="lineno"> 30 </span><span class="spaces"> </span><span class="nottickedoff">hit &lt;- doesDirectoryExist folder</span>
<span class="lineno"> 31 </span><span class="spaces"> </span><span class="nottickedoff">unless hit $</span>
<span class="lineno"> 32 </span><span class="spaces"> </span><span class="nottickedoff">downloadFile url $ \path -&gt; do</span>
<span class="lineno"> 33 </span><span class="spaces"> </span><span class="nottickedoff">inp &lt;- B.readFile path</span>
<span class="lineno"> 34 </span><span class="spaces"> </span><span class="nottickedoff">let inpSha = B8.unpack (encode (hash inp))</span>
<span class="lineno"> 35 </span><span class="spaces"> </span><span class="nottickedoff">if inpSha == sha256</span>
<span class="lineno"> 36 </span><span class="spaces"> </span><span class="nottickedoff">then do</span>
<span class="lineno"> 37 </span><span class="spaces"> </span><span class="nottickedoff">unpack folder path</span>
<span class="lineno"> 38 </span><span class="spaces"> </span><span class="nottickedoff">else</span>
<span class="lineno"> 39 </span><span class="spaces"> </span><span class="nottickedoff">error $</span>
<span class="lineno"> 40 </span><span class="spaces"> </span><span class="nottickedoff">&quot;URL &quot; ++ url ++ &quot;\n&quot;</span>
<span class="lineno"> 41 </span><span class="spaces"> </span><span class="nottickedoff">++ &quot; Expected SHA256: &quot;</span>
<span class="lineno"> 42 </span><span class="spaces"> </span><span class="nottickedoff">++ sha256</span>
<span class="lineno"> 43 </span><span class="spaces"> </span><span class="nottickedoff">++ &quot;\n&quot;</span>
<span class="lineno"> 44 </span><span class="spaces"> </span><span class="nottickedoff">++ &quot; Actual SHA256: &quot;</span>
<span class="lineno"> 45 </span><span class="spaces"> </span><span class="nottickedoff">++ inpSha</span>
<span class="lineno"> 46 </span><span class="spaces"> </span><span class="nottickedoff">return folder</span></span>
<span class="lineno"> 47 </span>
<span class="lineno"> 48 </span>{-# NOINLINE zipArchive #-}
<span class="lineno"> 49 </span>
<span class="lineno"> 50 </span>-- | Download and unpack zip archive. The returned path is the unpacked folder.
<span class="lineno"> 51 </span>zipArchive :: URL -&gt; SHA256 -&gt; FilePath
<span class="lineno"> 52 </span><span class="decl"><span class="nottickedoff">zipArchive url sha256 = unsafePerformIO $</span>
<span class="lineno"> 53 </span><span class="spaces"> </span><span class="nottickedoff">fetchStaticFile url sha256 $ \folder zipfile -&gt;</span>
<span class="lineno"> 54 </span><span class="spaces"> </span><span class="nottickedoff">callProcess &quot;unzip&quot; [&quot;-qq&quot;, &quot;-d&quot;, folder, zipfile]</span></span>
<span class="lineno"> 55 </span>
<span class="lineno"> 56 </span>{-# NOINLINE tarball #-}
<span class="lineno"> 57 </span>
<span class="lineno"> 58 </span>-- | Download and unpack tarball. The returned path is the unpacked folder.
<span class="lineno"> 59 </span>tarball :: URL -&gt; SHA256 -&gt; FilePath
<span class="lineno"> 60 </span><span class="decl"><span class="nottickedoff">tarball url sha256 = unsafePerformIO $</span>
<span class="lineno"> 61 </span><span class="spaces"> </span><span class="nottickedoff">fetchStaticFile url sha256 $ \folder tarfile -&gt;</span>
<span class="lineno"> 62 </span><span class="spaces"> </span><span class="nottickedoff">callProcess &quot;tar&quot; [&quot;--overwrite&quot;, &quot;--one-top-level=&quot; ++ folder, &quot;-xf&quot;, tarfile]</span></span>
<span class="lineno"> 63 </span>
<span class="lineno"> 64 </span>downloadFile :: URL -&gt; (FilePath -&gt; IO a) -&gt; IO a
<span class="lineno"> 65 </span><span class="decl"><span class="nottickedoff">downloadFile url action = do</span>
<span class="lineno"> 66 </span><span class="spaces"> </span><span class="nottickedoff">mbCurl &lt;- findExecutable &quot;curl&quot;</span>
<span class="lineno"> 67 </span><span class="spaces"> </span><span class="nottickedoff">mbWget &lt;- findExecutable &quot;wget&quot;</span>
<span class="lineno"> 68 </span><span class="spaces"> </span><span class="nottickedoff">case (mbCurl, mbWget) of</span>
<span class="lineno"> 69 </span><span class="spaces"> </span><span class="nottickedoff">(Just curl, _) -&gt; downloadFileCurl curl url action</span>
<span class="lineno"> 70 </span><span class="spaces"> </span><span class="nottickedoff">(_, Just wget) -&gt; downloadFileWget wget url action</span>
<span class="lineno"> 71 </span><span class="spaces"> </span><span class="nottickedoff">(Nothing, Nothing) -&gt; error &quot;curl/wget required to download files&quot;</span></span>
<span class="lineno"> 6 </span>
<span class="lineno"> 7 </span> -- * External Icon Datasets
<span class="lineno"> 8 </span> simpleIcon,
<span class="lineno"> 9 </span> simpleIconColor,
<span class="lineno"> 10 </span> simpleIcons,
<span class="lineno"> 11 </span> )
<span class="lineno"> 12 </span>where
<span class="lineno"> 13 </span>
<span class="lineno"> 14 </span>import Codec.Picture (PixelRGB8 (..))
<span class="lineno"> 15 </span>import Control.Monad (unless)
<span class="lineno"> 16 </span>import Crypto.Hash.SHA256 (hash)
<span class="lineno"> 17 </span>import Data.Aeson (decodeFileStrict)
<span class="lineno"> 18 </span>import qualified Data.ByteString as B (readFile)
<span class="lineno"> 19 </span>import Data.ByteString.Base64 (encode)
<span class="lineno"> 20 </span>import qualified Data.ByteString.Char8 as B8 (unpack)
<span class="lineno"> 21 </span>import Data.Char (isSpace, toLower)
<span class="lineno"> 22 </span>import Data.List (sort)
<span class="lineno"> 23 </span>import Data.Map (Map)
<span class="lineno"> 24 </span>import qualified Data.Map as M
<span class="lineno"> 25 </span>import Numeric (readHex)
<span class="lineno"> 26 </span>import Reanimate.Animation (SVG)
<span class="lineno"> 27 </span>import Reanimate.Constants (screenHeight, screenWidth)
<span class="lineno"> 28 </span>import Reanimate.Misc (getReanimateCacheDirectory, withTempFile)
<span class="lineno"> 29 </span>import Reanimate.Raster (mkImage)
<span class="lineno"> 30 </span>import System.Directory (doesDirectoryExist, doesFileExist, findExecutable, getDirectoryContents)
<span class="lineno"> 31 </span>import System.FilePath (splitExtension, (&lt;.&gt;), (&lt;/&gt;))
<span class="lineno"> 32 </span>import System.IO.Unsafe (unsafePerformIO)
<span class="lineno"> 33 </span>import System.Process (callProcess)
<span class="lineno"> 34 </span>
<span class="lineno"> 35 </span>-- | Resource address
<span class="lineno"> 36 </span>type URL = String
<span class="lineno"> 37 </span>
<span class="lineno"> 38 </span>-- | Resource hash
<span class="lineno"> 39 </span>type SHA256 = String
<span class="lineno"> 40 </span>
<span class="lineno"> 41 </span>fetchStaticFile :: URL -&gt; SHA256 -&gt; (FilePath -&gt; FilePath -&gt; IO ()) -&gt; IO FilePath
<span class="lineno"> 42 </span><span class="decl"><span class="nottickedoff">fetchStaticFile url sha256 unpack = do</span>
<span class="lineno"> 43 </span><span class="spaces"> </span><span class="nottickedoff">root &lt;- getReanimateCacheDirectory</span>
<span class="lineno"> 44 </span><span class="spaces"> </span><span class="nottickedoff">let folder = root &lt;/&gt; sha256</span>
<span class="lineno"> 45 </span><span class="spaces"> </span><span class="nottickedoff">hit &lt;- doesDirectoryExist folder</span>
<span class="lineno"> 46 </span><span class="spaces"> </span><span class="nottickedoff">unless hit $</span>
<span class="lineno"> 47 </span><span class="spaces"> </span><span class="nottickedoff">downloadFile url $ \path -&gt; do</span>
<span class="lineno"> 48 </span><span class="spaces"> </span><span class="nottickedoff">inp &lt;- B.readFile path</span>
<span class="lineno"> 49 </span><span class="spaces"> </span><span class="nottickedoff">let inpSha = B8.unpack (encode (hash inp))</span>
<span class="lineno"> 50 </span><span class="spaces"> </span><span class="nottickedoff">if inpSha == sha256</span>
<span class="lineno"> 51 </span><span class="spaces"> </span><span class="nottickedoff">then do</span>
<span class="lineno"> 52 </span><span class="spaces"> </span><span class="nottickedoff">unpack folder path</span>
<span class="lineno"> 53 </span><span class="spaces"> </span><span class="nottickedoff">else</span>
<span class="lineno"> 54 </span><span class="spaces"> </span><span class="nottickedoff">error $</span>
<span class="lineno"> 55 </span><span class="spaces"> </span><span class="nottickedoff">&quot;URL &quot; ++ url ++ &quot;\n&quot;</span>
<span class="lineno"> 56 </span><span class="spaces"> </span><span class="nottickedoff">++ &quot; Expected SHA256: &quot;</span>
<span class="lineno"> 57 </span><span class="spaces"> </span><span class="nottickedoff">++ sha256</span>
<span class="lineno"> 58 </span><span class="spaces"> </span><span class="nottickedoff">++ &quot;\n&quot;</span>
<span class="lineno"> 59 </span><span class="spaces"> </span><span class="nottickedoff">++ &quot; Actual SHA256: &quot;</span>
<span class="lineno"> 60 </span><span class="spaces"> </span><span class="nottickedoff">++ inpSha</span>
<span class="lineno"> 61 </span><span class="spaces"> </span><span class="nottickedoff">return folder</span></span>
<span class="lineno"> 62 </span>
<span class="lineno"> 63 </span>{-# NOINLINE zipArchive #-}
<span class="lineno"> 64 </span>
<span class="lineno"> 65 </span>-- | Download and unpack zip archive. The returned path is the unpacked folder.
<span class="lineno"> 66 </span>zipArchive :: URL -&gt; SHA256 -&gt; FilePath
<span class="lineno"> 67 </span><span class="decl"><span class="nottickedoff">zipArchive url sha256 = unsafePerformIO $</span>
<span class="lineno"> 68 </span><span class="spaces"> </span><span class="nottickedoff">fetchStaticFile url sha256 $ \folder zipfile -&gt;</span>
<span class="lineno"> 69 </span><span class="spaces"> </span><span class="nottickedoff">callProcess &quot;unzip&quot; [&quot;-qq&quot;, &quot;-d&quot;, folder, zipfile]</span></span>
<span class="lineno"> 70 </span>
<span class="lineno"> 71 </span>{-# NOINLINE tarball #-}
<span class="lineno"> 72 </span>
<span class="lineno"> 73 </span>downloadFileCurl :: FilePath -&gt; URL -&gt; (FilePath -&gt; IO a) -&gt; IO a
<span class="lineno"> 74 </span><span class="decl"><span class="nottickedoff">downloadFileCurl curl url action = withTempFile &quot;dl&quot; $ \path -&gt; do</span>
<span class="lineno"> 75 </span><span class="spaces"> </span><span class="nottickedoff">callProcess</span>
<span class="lineno"> 76 </span><span class="spaces"> </span><span class="nottickedoff">curl</span>
<span class="lineno"> 77 </span><span class="spaces"> </span><span class="nottickedoff">[ url,</span>
<span class="lineno"> 78 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--output&quot;,</span>
<span class="lineno"> 79 </span><span class="spaces"> </span><span class="nottickedoff">path,</span>
<span class="lineno"> 80 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--silent&quot;,</span>
<span class="lineno"> 81 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--show-error&quot;,</span>
<span class="lineno"> 82 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--max-filesize&quot;,</span>
<span class="lineno"> 83 </span><span class="spaces"> </span><span class="nottickedoff">&quot;10M&quot;</span>
<span class="lineno"> 84 </span><span class="spaces"> </span><span class="nottickedoff">]</span>
<span class="lineno"> 85 </span><span class="spaces"> </span><span class="nottickedoff">action path</span></span>
<span class="lineno"> 86 </span>
<span class="lineno"> 87 </span>downloadFileWget :: FilePath -&gt; URL -&gt; (FilePath -&gt; IO a) -&gt; IO a
<span class="lineno"> 88 </span><span class="decl"><span class="nottickedoff">downloadFileWget wget url action = withTempFile &quot;dl&quot; $ \path -&gt; do</span>
<span class="lineno"> 89 </span><span class="spaces"> </span><span class="nottickedoff">callProcess</span>
<span class="lineno"> 90 </span><span class="spaces"> </span><span class="nottickedoff">wget</span>
<span class="lineno"> 91 </span><span class="spaces"> </span><span class="nottickedoff">[ url,</span>
<span class="lineno"> 92 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--output-document=&quot; ++ path,</span>
<span class="lineno"> 93 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--quiet&quot;</span>
<span class="lineno"> 94 </span><span class="spaces"> </span><span class="nottickedoff">]</span>
<span class="lineno"> 95 </span><span class="spaces"> </span><span class="nottickedoff">action path</span></span>
<span class="lineno"> 73 </span>-- | Download and unpack tarball. The returned path is the unpacked folder.
<span class="lineno"> 74 </span>tarball :: URL -&gt; SHA256 -&gt; FilePath
<span class="lineno"> 75 </span><span class="decl"><span class="nottickedoff">tarball url sha256 = unsafePerformIO $</span>
<span class="lineno"> 76 </span><span class="spaces"> </span><span class="nottickedoff">fetchStaticFile url sha256 $ \folder tarfile -&gt;</span>
<span class="lineno"> 77 </span><span class="spaces"> </span><span class="nottickedoff">callProcess &quot;tar&quot; [&quot;--overwrite&quot;, &quot;--one-top-level=&quot; ++ folder, &quot;-xzf&quot;, tarfile]</span></span>
<span class="lineno"> 78 </span>
<span class="lineno"> 79 </span>downloadFile :: URL -&gt; (FilePath -&gt; IO a) -&gt; IO a
<span class="lineno"> 80 </span><span class="decl"><span class="nottickedoff">downloadFile url action = do</span>
<span class="lineno"> 81 </span><span class="spaces"> </span><span class="nottickedoff">mbCurl &lt;- findExecutable &quot;curl&quot;</span>
<span class="lineno"> 82 </span><span class="spaces"> </span><span class="nottickedoff">mbWget &lt;- findExecutable &quot;wget&quot;</span>
<span class="lineno"> 83 </span><span class="spaces"> </span><span class="nottickedoff">case (mbCurl, mbWget) of</span>
<span class="lineno"> 84 </span><span class="spaces"> </span><span class="nottickedoff">(Just curl, _) -&gt; downloadFileCurl curl url action</span>
<span class="lineno"> 85 </span><span class="spaces"> </span><span class="nottickedoff">(_, Just wget) -&gt; downloadFileWget wget url action</span>
<span class="lineno"> 86 </span><span class="spaces"> </span><span class="nottickedoff">(Nothing, Nothing) -&gt; error &quot;curl/wget required to download files&quot;</span></span>
<span class="lineno"> 87 </span>
<span class="lineno"> 88 </span>downloadFileCurl :: FilePath -&gt; URL -&gt; (FilePath -&gt; IO a) -&gt; IO a
<span class="lineno"> 89 </span><span class="decl"><span class="nottickedoff">downloadFileCurl curl url action = withTempFile &quot;dl&quot; $ \path -&gt; do</span>
<span class="lineno"> 90 </span><span class="spaces"> </span><span class="nottickedoff">callProcess</span>
<span class="lineno"> 91 </span><span class="spaces"> </span><span class="nottickedoff">curl</span>
<span class="lineno"> 92 </span><span class="spaces"> </span><span class="nottickedoff">[ url,</span>
<span class="lineno"> 93 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--location&quot;,</span>
<span class="lineno"> 94 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--output&quot;,</span>
<span class="lineno"> 95 </span><span class="spaces"> </span><span class="nottickedoff">path,</span>
<span class="lineno"> 96 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--silent&quot;,</span>
<span class="lineno"> 97 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--show-error&quot;,</span>
<span class="lineno"> 98 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--max-filesize&quot;,</span>
<span class="lineno"> 99 </span><span class="spaces"> </span><span class="nottickedoff">&quot;10M&quot;,</span>
<span class="lineno"> 100 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--max-time&quot;,</span>
<span class="lineno"> 101 </span><span class="spaces"> </span><span class="nottickedoff">&quot;60&quot;</span>
<span class="lineno"> 102 </span><span class="spaces"> </span><span class="nottickedoff">]</span>
<span class="lineno"> 103 </span><span class="spaces"> </span><span class="nottickedoff">action path</span></span>
<span class="lineno"> 104 </span>
<span class="lineno"> 105 </span>downloadFileWget :: FilePath -&gt; URL -&gt; (FilePath -&gt; IO a) -&gt; IO a
<span class="lineno"> 106 </span><span class="decl"><span class="nottickedoff">downloadFileWget wget url action = withTempFile &quot;dl&quot; $ \path -&gt; do</span>
<span class="lineno"> 107 </span><span class="spaces"> </span><span class="nottickedoff">callProcess</span>
<span class="lineno"> 108 </span><span class="spaces"> </span><span class="nottickedoff">wget</span>
<span class="lineno"> 109 </span><span class="spaces"> </span><span class="nottickedoff">[ url,</span>
<span class="lineno"> 110 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--output-document=&quot; ++ path,</span>
<span class="lineno"> 111 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--quiet&quot;</span>
<span class="lineno"> 112 </span><span class="spaces"> </span><span class="nottickedoff">]</span>
<span class="lineno"> 113 </span><span class="spaces"> </span><span class="nottickedoff">action path</span></span>
<span class="lineno"> 114 </span>
<span class="lineno"> 115 </span>
<span class="lineno"> 116 </span>
<span class="lineno"> 117 </span>-------------------------------------------------------------------------------
<span class="lineno"> 118 </span>-- SimpleIcons
<span class="lineno"> 119 </span>
<span class="lineno"> 120 </span>simpleIconsFolder :: FilePath
<span class="lineno"> 121 </span><span class="decl"><span class="nottickedoff">simpleIconsFolder =</span>
<span class="lineno"> 122 </span><span class="spaces"> </span><span class="nottickedoff">tarball</span>
<span class="lineno"> 123 </span><span class="spaces"> </span><span class="nottickedoff">&quot;https://github.com/simple-icons/simple-icons/archive/3.11.0.tar.gz&quot;</span>
<span class="lineno"> 124 </span><span class="spaces"> </span><span class="nottickedoff">&quot;NXa8TrHHuQofrPbqTf0pBGt1GDRfuQ4IcQ7kNEk9OcQ=&quot;</span>
<span class="lineno"> 125 </span><span class="spaces"> </span><span class="nottickedoff">&lt;/&gt; &quot;simple-icons-3.11.0&quot;</span></span>
<span class="lineno"> 126 </span>
<span class="lineno"> 127 </span>{-# NOINLINE simpleIconPath #-}
<span class="lineno"> 128 </span>simpleIconPath :: String -&gt; FilePath
<span class="lineno"> 129 </span><span class="decl"><span class="nottickedoff">simpleIconPath key = unsafePerformIO $ do</span>
<span class="lineno"> 130 </span><span class="spaces"> </span><span class="nottickedoff">let path = simpleIconsFolder &lt;/&gt; &quot;icons&quot; &lt;/&gt; key &lt;.&gt; &quot;svg&quot;</span>
<span class="lineno"> 131 </span><span class="spaces"> </span><span class="nottickedoff">hit &lt;- doesFileExist path</span>
<span class="lineno"> 132 </span><span class="spaces"> </span><span class="nottickedoff">if hit</span>
<span class="lineno"> 133 </span><span class="spaces"> </span><span class="nottickedoff">then pure path</span>
<span class="lineno"> 134 </span><span class="spaces"> </span><span class="nottickedoff">else error $ &quot;Key not found in simple-icons dataset: &quot; ++ show key</span></span>
<span class="lineno"> 135 </span>
<span class="lineno"> 136 </span>-- | Icons from &lt;http://simpleicons.org/&gt;. Version 3.11.0. License: CC0
<span class="lineno"> 137 </span>--
<span class="lineno"> 138 </span>-- @
<span class="lineno"> 139 </span>-- let icon = &quot;cplusplus&quot; in `Reanimate.mkGroup`
<span class="lineno"> 140 </span>-- [ `Reanimate.mkBackgroundPixel` (`Codec.Picture.Types.promotePixel` $ `simpleIconColor` icon)
<span class="lineno"> 141 </span>-- , `Reanimate.withFillOpacity` 1 $ `simpleIcon` icon ]
<span class="lineno"> 142 </span>-- @
<span class="lineno"> 143 </span>--
<span class="lineno"> 144 </span>-- &lt;&lt;docs/gifs/doc_simpleIcon.gif&gt;&gt;
<span class="lineno"> 145 </span>simpleIcon :: String -&gt; SVG
<span class="lineno"> 146 </span><span class="decl"><span class="nottickedoff">simpleIcon = mkImage screenWidth screenHeight . simpleIconPath</span></span>
<span class="lineno"> 147 </span>
<span class="lineno"> 148 </span>-- | Simple Icons svgs do not contain color. Instead, each icon has an associated color value.
<span class="lineno"> 149 </span>simpleIconColor :: String -&gt; PixelRGB8
<span class="lineno"> 150 </span><span class="decl"><span class="nottickedoff">simpleIconColor key =</span>
<span class="lineno"> 151 </span><span class="spaces"> </span><span class="nottickedoff">case M.lookup key simpleIconColors of</span>
<span class="lineno"> 152 </span><span class="spaces"> </span><span class="nottickedoff">Nothing -&gt; error $ &quot;Key not found in simple-icons dataset: &quot; ++ show key</span>
<span class="lineno"> 153 </span><span class="spaces"> </span><span class="nottickedoff">Just pixel -&gt; pixel</span></span>
<span class="lineno"> 154 </span>
<span class="lineno"> 155 </span>-- | Complete list of all Simple Icons.
<span class="lineno"> 156 </span>simpleIconColors :: Map String PixelRGB8
<span class="lineno"> 157 </span><span class="decl"><span class="nottickedoff">simpleIconColors = unsafePerformIO $ do</span>
<span class="lineno"> 158 </span><span class="spaces"> </span><span class="nottickedoff">let path = simpleIconsFolder &lt;/&gt; &quot;_data&quot; &lt;/&gt; &quot;simple-icons.json&quot;</span>
<span class="lineno"> 159 </span><span class="spaces"> </span><span class="nottickedoff">mbRet &lt;- decodeFileStrict path</span>
<span class="lineno"> 160 </span><span class="spaces"> </span><span class="nottickedoff">let parsed = do</span>
<span class="lineno"> 161 </span><span class="spaces"> </span><span class="nottickedoff">m &lt;- mbRet</span>
<span class="lineno"> 162 </span><span class="spaces"> </span><span class="nottickedoff">icons &lt;- M.lookup &quot;icons&quot; m</span>
<span class="lineno"> 163 </span><span class="spaces"> </span><span class="nottickedoff">pure $</span>
<span class="lineno"> 164 </span><span class="spaces"> </span><span class="nottickedoff">M.fromList</span>
<span class="lineno"> 165 </span><span class="spaces"> </span><span class="nottickedoff">[ (fromTitle title, parseHex hex) | icon &lt;- icons, Just title &lt;- [M.lookup &quot;title&quot; icon], Just hex &lt;- [M.lookup &quot;hex&quot; icon]</span>
<span class="lineno"> 166 </span><span class="spaces"> </span><span class="nottickedoff">]</span>
<span class="lineno"> 167 </span><span class="spaces"> </span><span class="nottickedoff">case parsed of</span>
<span class="lineno"> 168 </span><span class="spaces"> </span><span class="nottickedoff">Nothing -&gt; error &quot;Invalid json in simpleIcons&quot;</span>
<span class="lineno"> 169 </span><span class="spaces"> </span><span class="nottickedoff">Just v -&gt; pure v</span>
<span class="lineno"> 170 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 171 </span><span class="spaces"> </span><span class="nottickedoff">fromTitle :: String -&gt; String</span>
<span class="lineno"> 172 </span><span class="spaces"> </span><span class="nottickedoff">fromTitle = replaceChars . map toLower</span>
<span class="lineno"> 173 </span><span class="spaces"></span><span class="nottickedoff"></span>
<span class="lineno"> 174 </span><span class="spaces"> </span><span class="nottickedoff">replaceChars :: String -&gt; String</span>
<span class="lineno"> 175 </span><span class="spaces"> </span><span class="nottickedoff">replaceChars ('.' : x : xs) = &quot;dot-&quot; ++ replaceChars (x : xs)</span>
<span class="lineno"> 176 </span><span class="spaces"> </span><span class="nottickedoff">replaceChars &quot;.&quot; = &quot;dot&quot;</span>
<span class="lineno"> 177 </span><span class="spaces"> </span><span class="nottickedoff">replaceChars (x : '.' : []) = replaceChars (x : &quot;-dot&quot;)</span>
<span class="lineno"> 178 </span><span class="spaces"> </span><span class="nottickedoff">replaceChars (x : '.' : xs) = replaceChars (x : &quot;-dot-&quot; ++ xs)</span>
<span class="lineno"> 179 </span><span class="spaces"> </span><span class="nottickedoff">replaceChars (x : xs)</span>
<span class="lineno"> 180 </span><span class="spaces"> </span><span class="nottickedoff">| isSpace x || x `elem` &quot;!:'&quot; = replaceChars xs</span>
<span class="lineno"> 181 </span><span class="spaces"> </span><span class="nottickedoff">replaceChars ('&amp;' : xs) = &quot;-and-&quot; ++ replaceChars xs</span>
<span class="lineno"> 182 </span><span class="spaces"> </span><span class="nottickedoff">replaceChars ('+' : xs) = &quot;plus&quot; ++ replaceChars xs</span>
<span class="lineno"> 183 </span><span class="spaces"> </span><span class="nottickedoff">replaceChars (x : xs)</span>
<span class="lineno"> 184 </span><span class="spaces"> </span><span class="nottickedoff">| x `elem` &quot;àáâãä&quot; = 'a' : replaceChars xs</span>
<span class="lineno"> 185 </span><span class="spaces"> </span><span class="nottickedoff">| x `elem` &quot;ìíîï&quot; = 'i' : replaceChars xs</span>
<span class="lineno"> 186 </span><span class="spaces"> </span><span class="nottickedoff">| x `elem` &quot;èéêë&quot; = 'e' : replaceChars xs</span>
<span class="lineno"> 187 </span><span class="spaces"> </span><span class="nottickedoff">| x `elem` &quot;šś&quot; = 's' : replaceChars xs</span>
<span class="lineno"> 188 </span><span class="spaces"> </span><span class="nottickedoff">replaceChars (x : xs) = x : replaceChars xs</span>
<span class="lineno"> 189 </span><span class="spaces"> </span><span class="nottickedoff">replaceChars [] = []</span>
<span class="lineno"> 190 </span><span class="spaces"> </span><span class="nottickedoff">parseHex :: String -&gt; PixelRGB8</span>
<span class="lineno"> 191 </span><span class="spaces"> </span><span class="nottickedoff">parseHex hex = PixelRGB8 (p 0) (p 2) (p 4)</span>
<span class="lineno"> 192 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 193 </span><span class="spaces"> </span><span class="nottickedoff">p offset = case readHex (take 2 $ drop offset hex) of</span>
<span class="lineno"> 194 </span><span class="spaces"> </span><span class="nottickedoff">[(num, &quot;&quot;)] -&gt; num</span>
<span class="lineno"> 195 </span><span class="spaces"> </span><span class="nottickedoff">_ -&gt; error $ &quot;Invalid hex: &quot; ++ (take 2 $ drop offset hex)</span></span>
<span class="lineno"> 196 </span>
<span class="lineno"> 197 </span>{-# NOINLINE simpleIcons #-}
<span class="lineno"> 198 </span>simpleIcons :: [String]
<span class="lineno"> 199 </span><span class="decl"><span class="nottickedoff">simpleIcons = unsafePerformIO $ do</span>
<span class="lineno"> 200 </span><span class="spaces"> </span><span class="nottickedoff">let folder = simpleIconsFolder &lt;/&gt; &quot;icons&quot;</span>
<span class="lineno"> 201 </span><span class="spaces"> </span><span class="nottickedoff">files &lt;- getDirectoryContents folder</span>
<span class="lineno"> 202 </span><span class="spaces"> </span><span class="nottickedoff">return $</span>
<span class="lineno"> 203 </span><span class="spaces"> </span><span class="nottickedoff">sort</span>
<span class="lineno"> 204 </span><span class="spaces"> </span><span class="nottickedoff">[key | file &lt;- files, let (key, ext) = splitExtension file, ext == &quot;.svg&quot;]</span></span>
</pre>
</body>

View file

@ -48,339 +48,376 @@ span.spaces { background: white }
<span class="lineno"> 29 </span> noto,
<span class="lineno"> 30 </span> helvet,
<span class="lineno"> 31 </span> libertine,
<span class="lineno"> 32 </span> )
<span class="lineno"> 33 </span>where
<span class="lineno"> 34 </span>
<span class="lineno"> 35 </span>import Control.Lens
<span class="lineno"> 36 </span>import qualified Data.ByteString as B
<span class="lineno"> 37 </span>import Data.Hashable
<span class="lineno"> 38 </span>import Data.Monoid
<span class="lineno"> 39 </span>import Data.Text (Text)
<span class="lineno"> 40 </span>import qualified Data.Text as T
<span class="lineno"> 41 </span>import qualified Data.Text.Encoding as T
<span class="lineno"> 42 </span>import GHC.Generics (Generic)
<span class="lineno"> 43 </span>import Graphics.SvgTree
<span class="lineno"> 44 </span> ( Tree,
<span class="lineno"> 45 </span> clipPathRef,
<span class="lineno"> 46 </span> clipRule,
<span class="lineno"> 47 </span> mapTree,
<span class="lineno"> 48 </span> parseSvgFile,
<span class="lineno"> 49 </span> strokeColor,
<span class="lineno"> 50 </span> pattern ClipPathTree,
<span class="lineno"> 51 </span> pattern None,
<span class="lineno"> 52 </span> )
<span class="lineno"> 53 </span>import Reanimate.Animation (SVG)
<span class="lineno"> 54 </span>import Reanimate.Cache
<span class="lineno"> 55 </span>import Reanimate.External
<span class="lineno"> 56 </span>import Reanimate.Misc
<span class="lineno"> 57 </span>import Reanimate.Parameters
<span class="lineno"> 58 </span>import Reanimate.Svg
<span class="lineno"> 59 </span>import System.FilePath
<span class="lineno"> 60 </span> ( replaceExtension,
<span class="lineno"> 61 </span> takeFileName,
<span class="lineno"> 62 </span> (&lt;/&gt;),
<span class="lineno"> 63 </span> )
<span class="lineno"> 64 </span>import System.IO.Unsafe (unsafePerformIO)
<span class="lineno"> 65 </span>
<span class="lineno"> 66 </span>-- | TeX backends. They have different features and capabilities.
<span class="lineno"> 67 </span>data TexEngine = LaTeX | XeLaTeX | LuaLaTeX
<span class="lineno"> 68 </span> deriving (Generic, Hashable, <span class="decl"><span class="nottickedoff">Eq</span></span>, <span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff">Ord</span></span></span></span></span></span></span></span></span></span>, <span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff">Read</span></span></span></span></span></span>, <span class="decl"><span class="nottickedoff">Show</span></span>)
<span class="lineno"> 69 </span>
<span class="lineno"> 70 </span>-- | TeX configurations can load packages and set up environments for tex scripts.
<span class="lineno"> 71 </span>data TexConfig = TexConfig
<span class="lineno"> 72 </span> { <span class="nottickedoff"><span class="decl"><span class="nottickedoff">texConfigEngine</span></span></span> :: TexEngine,
<span class="lineno"> 73 </span> <span class="nottickedoff"><span class="decl"><span class="nottickedoff">texConfigHeaders</span></span></span> :: [T.Text],
<span class="lineno"> 74 </span> <span class="nottickedoff"><span class="decl"><span class="nottickedoff">texConfigPostScript</span></span></span> :: [T.Text]
<span class="lineno"> 75 </span> }
<span class="lineno"> 76 </span> deriving (Generic, Hashable, <span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff">Read</span></span></span></span></span></span>, <span class="decl"><span class="nottickedoff">Show</span></span>, <span class="decl"><span class="nottickedoff">Eq</span></span>, <span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff">Ord</span></span></span></span></span></span></span></span></span></span>)
<span class="lineno"> 77 </span>
<span class="lineno"> 78 </span>-- | Render TeX script using a given configuration.
<span class="lineno"> 79 </span>latexCfg :: TexConfig -&gt; T.Text -&gt; SVG
<span class="lineno"> 80 </span><span class="decl"><span class="nottickedoff">latexCfg (TexConfig engine headers postscript) =</span>
<span class="lineno"> 81 </span><span class="spaces"> </span><span class="nottickedoff">gen headers postscript</span>
<span class="lineno"> 82 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 83 </span><span class="spaces"> </span><span class="nottickedoff">gen =</span>
<span class="lineno"> 84 </span><span class="spaces"> </span><span class="nottickedoff">case engine of</span>
<span class="lineno"> 85 </span><span class="spaces"> </span><span class="nottickedoff">LaTeX -&gt; someTexWithHeaders engine &quot;latex&quot; &quot;dvi&quot; []</span>
<span class="lineno"> 86 </span><span class="spaces"> </span><span class="nottickedoff">XeLaTeX -&gt; someTexWithHeaders engine &quot;xelatex&quot; &quot;xdv&quot; [&quot;-no-pdf&quot;]</span>
<span class="lineno"> 87 </span><span class="spaces"> </span><span class="nottickedoff">LuaLaTeX -&gt; someTexWithHeaders engine &quot;lualatex&quot; &quot;pdf&quot; []</span></span>
<span class="lineno"> 88 </span>
<span class="lineno"> 89 </span>-- | Invoke latex and import the result as an SVG object. SVG objects are
<span class="lineno"> 90 </span>-- cached to improve performance.
<span class="lineno"> 91 </span>--
<span class="lineno"> 92 </span>-- Example:
<span class="lineno"> 93 </span>--
<span class="lineno"> 94 </span>-- &gt; latex &quot;$e^{i\\pi}+1=0$&quot;
<span class="lineno"> 95 </span>--
<span class="lineno"> 96 </span>-- &lt;&lt;docs/gifs/doc_latex.gif&gt;&gt;
<span class="lineno"> 97 </span>latex :: T.Text -&gt; Tree
<span class="lineno"> 98 </span><span class="decl"><span class="istickedoff">latex = latexWithHeaders <span class="nottickedoff">[]</span></span></span>
<span class="lineno"> 99 </span>
<span class="lineno"> 100 </span>-- | Invoke latex with extra script headers.
<span class="lineno"> 101 </span>latexWithHeaders :: [T.Text] -&gt; T.Text -&gt; Tree
<span class="lineno"> 102 </span><span class="decl"><span class="istickedoff">latexWithHeaders = someTexWithHeaders <span class="nottickedoff">LaTeX</span> <span class="nottickedoff">&quot;latex&quot;</span> <span class="nottickedoff">&quot;dvi&quot;</span> <span class="nottickedoff">[]</span> <span class="nottickedoff">[]</span></span></span>
<span class="lineno"> 103 </span>
<span class="lineno"> 104 </span>someTexWithHeaders ::
<span class="lineno"> 105 </span> TexEngine -&gt;
<span class="lineno"> 106 </span> String -&gt;
<span class="lineno"> 107 </span> String -&gt;
<span class="lineno"> 108 </span> [String] -&gt;
<span class="lineno"> 109 </span> [T.Text] -&gt;
<span class="lineno"> 110 </span> [T.Text] -&gt;
<span class="lineno"> 111 </span> T.Text -&gt;
<span class="lineno"> 112 </span> Tree
<span class="lineno"> 113 </span><span class="decl"><span class="istickedoff">someTexWithHeaders _engine _exec _dvi _args _headers _postscript tex</span>
<span class="lineno"> 114 </span><span class="spaces"> </span><span class="istickedoff">| <span class="tickonlytrue">pNoExternals</span> = mkText tex</span>
<span class="lineno"> 115 </span><span class="spaces"></span><span class="istickedoff">someTexWithHeaders engine exec dvi args headers postscript tex =</span>
<span class="lineno"> 116 </span><span class="spaces"> </span><span class="istickedoff"><span class="nottickedoff">(unsafePerformIO . (cacheMem . cacheDiskSvg) (latexToSVG engine dvi exec args))</span></span>
<span class="lineno"> 117 </span><span class="spaces"> </span><span class="istickedoff"><span class="nottickedoff">script</span></span>
<span class="lineno"> 118 </span><span class="spaces"> </span><span class="istickedoff">where</span>
<span class="lineno"> 119 </span><span class="spaces"> </span><span class="istickedoff"><span class="nottickedoff">script = mkTexScript exec args headers (T.unlines (postscript ++ [tex]))</span></span></span>
<span class="lineno"> 120 </span>
<span class="lineno"> 121 </span>-- | Invoke latex and separate results.
<span class="lineno"> 122 </span>latexChunks :: [T.Text] -&gt; [Tree]
<span class="lineno"> 123 </span><span class="decl"><span class="nottickedoff">latexChunks chunks | pNoExternals = map mkText chunks</span>
<span class="lineno"> 124 </span><span class="spaces"></span><span class="nottickedoff">latexChunks chunks = worker (svgGlyphs $ latex $ T.concat chunks) chunks</span>
<span class="lineno"> 125 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 126 </span><span class="spaces"> </span><span class="nottickedoff">merge lst = mkGroup [fmt svg | (fmt, _, svg) &lt;- lst]</span>
<span class="lineno"> 127 </span><span class="spaces"> </span><span class="nottickedoff">worker [] [] = []</span>
<span class="lineno"> 128 </span><span class="spaces"> </span><span class="nottickedoff">worker _ [] = error &quot;latex chunk mismatch&quot;</span>
<span class="lineno"> 129 </span><span class="spaces"> </span><span class="nottickedoff">worker everything (x : xs) =</span>
<span class="lineno"> 130 </span><span class="spaces"> </span><span class="nottickedoff">let width = length $ svgGlyphs (latex x)</span>
<span class="lineno"> 131 </span><span class="spaces"> </span><span class="nottickedoff">in merge (take width everything) : worker (drop width everything) xs</span></span>
<span class="lineno"> 132 </span>
<span class="lineno"> 133 </span>-- | Invoke xelatex and import the result as an SVG object. SVG objects are
<span class="lineno"> 134 </span>-- cached to improve performance. Xelatex has support for non-western scripts.
<span class="lineno"> 135 </span>xelatex :: Text -&gt; Tree
<span class="lineno"> 136 </span><span class="decl"><span class="nottickedoff">xelatex = xelatexWithHeaders []</span></span>
<span class="lineno"> 137 </span>
<span class="lineno"> 138 </span>-- | Invoke xelatex with extra script headers.
<span class="lineno"> 139 </span>xelatexWithHeaders :: [T.Text] -&gt; T.Text -&gt; Tree
<span class="lineno"> 140 </span><span class="decl"><span class="nottickedoff">xelatexWithHeaders = someTexWithHeaders XeLaTeX &quot;xelatex&quot; &quot;xdv&quot; [] [&quot;-no-pdf&quot;]</span></span>
<span class="lineno"> 141 </span>
<span class="lineno"> 142 </span>-- | Invoke xelatex with &quot;\usepackage[UTF8]{ctex}&quot; and import the result as an
<span class="lineno"> 143 </span>-- SVG object. SVG objects are cached to improve performance. Xelatex has
<span class="lineno"> 144 </span>-- support for non-western scripts.
<span class="lineno"> 145 </span>--
<span class="lineno"> 146 </span>-- Example:
<span class="lineno"> 147 </span>--
<span class="lineno"> 148 </span>-- &gt; ctex &quot;中文&quot;
<span class="lineno"> 149 </span>--
<span class="lineno"> 150 </span>-- &lt;&lt;docs/gifs/doc_ctex.gif&gt;&gt;
<span class="lineno"> 151 </span>ctex :: T.Text -&gt; Tree
<span class="lineno"> 152 </span><span class="decl"><span class="nottickedoff">ctex = ctexWithHeaders []</span></span>
<span class="lineno"> 153 </span>
<span class="lineno"> 154 </span>-- | Invoke xelatex with extra script headers + ctex headers.
<span class="lineno"> 155 </span>ctexWithHeaders :: [T.Text] -&gt; T.Text -&gt; Tree
<span class="lineno"> 156 </span><span class="decl"><span class="nottickedoff">ctexWithHeaders headers = xelatexWithHeaders (&quot;\\usepackage[UTF8]{ctex}&quot; : headers)</span></span>
<span class="lineno"> 157 </span>
<span class="lineno"> 158 </span>-- | Invoke latex and import the result as an SVG object. SVG objects are
<span class="lineno"> 159 </span>-- cached to improve performance. This wraps the TeX code in an 'align*'
<span class="lineno"> 160 </span>-- context.
<span class="lineno"> 161 </span>--
<span class="lineno"> 162 </span>-- Example:
<span class="lineno"> 163 </span>--
<span class="lineno"> 164 </span>-- &gt; latexAlign &quot;R = \\frac{{\\Delta x}}{{kA}}&quot;
<span class="lineno"> 165 </span>--
<span class="lineno"> 166 </span>-- &lt;&lt;docs/gifs/doc_latexAlign.gif&gt;&gt;
<span class="lineno"> 167 </span>latexAlign :: Text -&gt; Tree
<span class="lineno"> 168 </span><span class="decl"><span class="istickedoff">latexAlign tex = latex $ T.unlines [&quot;\\begin{align*}&quot;, tex, &quot;\\end{align*}&quot;]</span></span>
<span class="lineno"> 169 </span>
<span class="lineno"> 170 </span>postprocess :: Tree -&gt; Tree
<span class="lineno"> 171 </span><span class="decl"><span class="nottickedoff">postprocess =</span>
<span class="lineno"> 172 </span><span class="spaces"> </span><span class="nottickedoff">simplify</span>
<span class="lineno"> 173 </span><span class="spaces"> </span><span class="nottickedoff">. lowerTransformations</span>
<span class="lineno"> 174 </span><span class="spaces"> </span><span class="nottickedoff">. scaleXY 0.1 (-0.1)</span>
<span class="lineno"> 175 </span><span class="spaces"> </span><span class="nottickedoff">. removeClipPaths</span>
<span class="lineno"> 176 </span><span class="spaces"> </span><span class="nottickedoff">. lowerIds</span>
<span class="lineno"> 177 </span><span class="spaces"> </span><span class="nottickedoff">. mapTree clearDrawAttr</span>
<span class="lineno"> 178 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 179 </span><span class="spaces"> </span><span class="nottickedoff">clearDrawAttr t = t &amp; strokeColor .~ Last Nothing</span></span>
<span class="lineno"> 180 </span>
<span class="lineno"> 181 </span>enginePostprocess :: TexEngine -&gt; Tree -&gt; Tree
<span class="lineno"> 182 </span><span class="decl"><span class="nottickedoff">enginePostprocess LuaLaTeX svg = translate 0 (svgHeight svg) svg</span>
<span class="lineno"> 183 </span><span class="spaces"></span><span class="nottickedoff">enginePostprocess _ svg = svg</span></span>
<span class="lineno"> 184 </span>
<span class="lineno"> 185 </span>removeClipPaths :: SVG -&gt; SVG
<span class="lineno"> 186 </span><span class="decl"><span class="nottickedoff">removeClipPaths = mapTree worker</span>
<span class="lineno"> 187 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 188 </span><span class="spaces"> </span><span class="nottickedoff">worker ClipPathTree {} = None</span>
<span class="lineno"> 189 </span><span class="spaces"> </span><span class="nottickedoff">worker t = t &amp; clipRule .~ Last Nothing &amp; clipPathRef .~ Last Nothing</span></span>
<span class="lineno"> 190 </span>
<span class="lineno"> 191 </span>-- executable, arguments, header, tex
<span class="lineno"> 192 </span>latexToSVG :: TexEngine -&gt; String -&gt; String -&gt; [String] -&gt; Text -&gt; IO Tree
<span class="lineno"> 193 </span><span class="decl"><span class="nottickedoff">latexToSVG engine dviExt latexExec latexArgs tex = do</span>
<span class="lineno"> 194 </span><span class="spaces"> </span><span class="nottickedoff">latexBin &lt;- requireExecutable latexExec</span>
<span class="lineno"> 195 </span><span class="spaces"> </span><span class="nottickedoff">withTempDir $ \tmp_dir -&gt; withTempFile &quot;tex&quot; $ \tex_file -&gt;</span>
<span class="lineno"> 196 </span><span class="spaces"> </span><span class="nottickedoff">withTempFile &quot;svg&quot; $ \svg_file -&gt; do</span>
<span class="lineno"> 197 </span><span class="spaces"> </span><span class="nottickedoff">let dvi_file =</span>
<span class="lineno"> 198 </span><span class="spaces"> </span><span class="nottickedoff">tmp_dir &lt;/&gt; replaceExtension (takeFileName tex_file) dviExt</span>
<span class="lineno"> 199 </span><span class="spaces"> </span><span class="nottickedoff">B.writeFile tex_file (T.encodeUtf8 tex)</span>
<span class="lineno"> 200 </span><span class="spaces"> </span><span class="nottickedoff">runCmd</span>
<span class="lineno"> 201 </span><span class="spaces"> </span><span class="nottickedoff">latexBin</span>
<span class="lineno"> 202 </span><span class="spaces"> </span><span class="nottickedoff">( latexArgs</span>
<span class="lineno"> 203 </span><span class="spaces"> </span><span class="nottickedoff">++ [ &quot;-interaction=nonstopmode&quot;,</span>
<span class="lineno"> 204 </span><span class="spaces"> </span><span class="nottickedoff">&quot;-halt-on-error&quot;,</span>
<span class="lineno"> 205 </span><span class="spaces"> </span><span class="nottickedoff">&quot;-output-directory=&quot; ++ tmp_dir,</span>
<span class="lineno"> 206 </span><span class="spaces"> </span><span class="nottickedoff">tex_file</span>
<span class="lineno"> 207 </span><span class="spaces"> </span><span class="nottickedoff">]</span>
<span class="lineno"> 208 </span><span class="spaces"> </span><span class="nottickedoff">)</span>
<span class="lineno"> 209 </span><span class="spaces"> </span><span class="nottickedoff">if dviExt == &quot;pdf&quot;</span>
<span class="lineno"> 210 </span><span class="spaces"> </span><span class="nottickedoff">then do</span>
<span class="lineno"> 211 </span><span class="spaces"> </span><span class="nottickedoff">pdf2svg &lt;- requireExecutable &quot;pdf2svg&quot;</span>
<span class="lineno"> 212 </span><span class="spaces"> </span><span class="nottickedoff">runCmd</span>
<span class="lineno"> 213 </span><span class="spaces"> </span><span class="nottickedoff">pdf2svg</span>
<span class="lineno"> 214 </span><span class="spaces"> </span><span class="nottickedoff">[dvi_file, svg_file]</span>
<span class="lineno"> 215 </span><span class="spaces"> </span><span class="nottickedoff">else do</span>
<span class="lineno"> 216 </span><span class="spaces"> </span><span class="nottickedoff">dvisvgm &lt;- requireExecutable &quot;dvisvgm&quot;</span>
<span class="lineno"> 217 </span><span class="spaces"> </span><span class="nottickedoff">runCmd</span>
<span class="lineno"> 218 </span><span class="spaces"> </span><span class="nottickedoff">dvisvgm</span>
<span class="lineno"> 219 </span><span class="spaces"> </span><span class="nottickedoff">[ dvi_file,</span>
<span class="lineno"> 220 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--precision=5&quot;,</span>
<span class="lineno"> 221 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--exact&quot;, -- better bboxes.</span>
<span class="lineno"> 222 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--no-fonts&quot;, -- use glyphs instead of fonts.</span>
<span class="lineno"> 223 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--verbosity=0&quot;,</span>
<span class="lineno"> 224 </span><span class="spaces"> </span><span class="nottickedoff">&quot;-o&quot;,</span>
<span class="lineno"> 225 </span><span class="spaces"> </span><span class="nottickedoff">svg_file</span>
<span class="lineno"> 226 </span><span class="spaces"> </span><span class="nottickedoff">]</span>
<span class="lineno"> 227 </span><span class="spaces"> </span><span class="nottickedoff">svg_data &lt;- B.readFile svg_file</span>
<span class="lineno"> 228 </span><span class="spaces"> </span><span class="nottickedoff">case parseSvgFile svg_file svg_data of</span>
<span class="lineno"> 229 </span><span class="spaces"> </span><span class="nottickedoff">Nothing -&gt; error &quot;Malformed svg&quot;</span>
<span class="lineno"> 230 </span><span class="spaces"> </span><span class="nottickedoff">Just svg -&gt;</span>
<span class="lineno"> 231 </span><span class="spaces"> </span><span class="nottickedoff">return $</span>
<span class="lineno"> 232 </span><span class="spaces"> </span><span class="nottickedoff">enginePostprocess engine $</span>
<span class="lineno"> 233 </span><span class="spaces"> </span><span class="nottickedoff">postprocess $ unbox $ replaceUses svg</span></span>
<span class="lineno"> 234 </span>
<span class="lineno"> 235 </span>mkTexScript :: String -&gt; [String] -&gt; [Text] -&gt; Text -&gt; Text
<span class="lineno"> 236 </span><span class="decl"><span class="nottickedoff">mkTexScript latexExec latexArgs texHeaders tex =</span>
<span class="lineno"> 237 </span><span class="spaces"> </span><span class="nottickedoff">T.unlines $</span>
<span class="lineno"> 238 </span><span class="spaces"> </span><span class="nottickedoff">[ &quot;% &quot; &lt;&gt; T.pack (unwords (latexExec : latexArgs)),</span>
<span class="lineno"> 239 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\documentclass[preview]{standalone}&quot;,</span>
<span class="lineno"> 240 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\usepackage{amsmath}&quot;,</span>
<span class="lineno"> 241 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\usepackage{gensymb}&quot;</span>
<span class="lineno"> 242 </span><span class="spaces"> </span><span class="nottickedoff">]</span>
<span class="lineno"> 243 </span><span class="spaces"> </span><span class="nottickedoff">++ texHeaders</span>
<span class="lineno"> 244 </span><span class="spaces"> </span><span class="nottickedoff">++ [ &quot;\\usepackage[english]{babel}&quot;,</span>
<span class="lineno"> 245 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\linespread{1}&quot;,</span>
<span class="lineno"> 246 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\begin{document}&quot;,</span>
<span class="lineno"> 247 </span><span class="spaces"> </span><span class="nottickedoff">tex,</span>
<span class="lineno"> 248 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\end{document}&quot;</span>
<span class="lineno"> 249 </span><span class="spaces"> </span><span class="nottickedoff">]</span></span>
<span class="lineno"> 250 </span>
<span class="lineno"> 251 </span>{- Packages used by manim.
<span class="lineno"> 252 </span>
<span class="lineno"> 253 </span>\\\usepackage{amsmath}\n\
<span class="lineno"> 254 </span>\\\usepackage{amssymb}\n\
<span class="lineno"> 255 </span>\\\usepackage{dsfont}\n\
<span class="lineno"> 256 </span>\\\usepackage{setspace}\n\
<span class="lineno"> 257 </span>\\\usepackage{relsize}\n\
<span class="lineno"> 258 </span>\\\usepackage{textcomp}\n\
<span class="lineno"> 259 </span>\\\usepackage{mathrsfs}\n\
<span class="lineno"> 260 </span>\\\usepackage{calligra}\n\
<span class="lineno"> 261 </span>\\\usepackage{wasysym}\n\
<span class="lineno"> 262 </span>\\\usepackage{ragged2e}\n\
<span class="lineno"> 263 </span>\\\usepackage{physics}\n\
<span class="lineno"> 264 </span>\\\usepackage{xcolor}\n\
<span class="lineno"> 265 </span>\\\usepackage{textcomp}\n\
<span class="lineno"> 266 </span>\\\usepackage{xfrac}\n\
<span class="lineno"> 267 </span>\\\usepackage{microtype}\n\
<span class="lineno"> 268 </span>-}
<span class="lineno"> 269 </span>
<span class="lineno"> 270 </span>-- | Chalkduster configuration. Depends on lualatex.
<span class="lineno"> 271 </span>-- Font files are automatically downloaded.
<span class="lineno"> 272 </span>--
<span class="lineno"> 273 </span>-- Example:
<span class="lineno"> 274 </span>--
<span class="lineno"> 275 </span>-- @
<span class="lineno"> 276 </span>-- `latexCfg` `chalkduster` &quot;chalkduster&quot;
<span class="lineno"> 277 </span>-- @
<span class="lineno"> 278 </span>--
<span class="lineno"> 279 </span>-- &lt;&lt;docs/gifs/doc_chalkduster.gif&gt;&gt;
<span class="lineno"> 280 </span>chalkduster :: TexConfig
<span class="lineno"> 281 </span><span class="decl"><span class="nottickedoff">chalkduster =</span>
<span class="lineno"> 282 </span><span class="spaces"> </span><span class="nottickedoff">TexConfig</span>
<span class="lineno"> 283 </span><span class="spaces"> </span><span class="nottickedoff">{ texConfigEngine = XeLaTeX,</span>
<span class="lineno"> 284 </span><span class="spaces"> </span><span class="nottickedoff">texConfigHeaders =</span>
<span class="lineno"> 285 </span><span class="spaces"> </span><span class="nottickedoff">[ &quot;\\usepackage[no-math]{fontspec}&quot;,</span>
<span class="lineno"> 286 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\setmainfont[Mapping=tex-text,Path={&quot; &lt;&gt; chalkdusterFont &lt;&gt; &quot;/},Extension=.ttf]{Chalkduster}&quot;,</span>
<span class="lineno"> 287 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\usepackage[defaultmathsizes]{mathastext}&quot;</span>
<span class="lineno"> 288 </span><span class="spaces"> </span><span class="nottickedoff">],</span>
<span class="lineno"> 289 </span><span class="spaces"> </span><span class="nottickedoff">texConfigPostScript = []</span>
<span class="lineno"> 290 </span><span class="spaces"> </span><span class="nottickedoff">}</span>
<span class="lineno"> 291 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 292 </span><span class="spaces"> </span><span class="nottickedoff">chalkdusterFont =</span>
<span class="lineno"> 293 </span><span class="spaces"> </span><span class="nottickedoff">T.pack $</span>
<span class="lineno"> 294 </span><span class="spaces"> </span><span class="nottickedoff">zipArchive</span>
<span class="lineno"> 295 </span><span class="spaces"> </span><span class="nottickedoff">&quot;https://www.ffonts.net/Chalkduster.font.zip&quot;</span>
<span class="lineno"> 296 </span><span class="spaces"> </span><span class="nottickedoff">&quot;Wplv4RjuFiI0hDQnAM5MVHl2evrZqWstRLdVAfBomCM=&quot;</span></span>
<span class="lineno"> 297 </span>
<span class="lineno"> 298 </span>-- | Calligra configuration.
<span class="lineno"> 299 </span>--
<span class="lineno"> 300 </span>-- Example:
<span class="lineno"> 301 </span>--
<span class="lineno"> 32 </span> biolinum,
<span class="lineno"> 33 </span> droidSerif,
<span class="lineno"> 34 </span> droidSans,
<span class="lineno"> 35 </span> )
<span class="lineno"> 36 </span>where
<span class="lineno"> 37 </span>
<span class="lineno"> 38 </span>import Control.Lens
<span class="lineno"> 39 </span>import qualified Data.ByteString as B
<span class="lineno"> 40 </span>import Data.Hashable
<span class="lineno"> 41 </span>import Data.Monoid
<span class="lineno"> 42 </span>import Data.Text (Text)
<span class="lineno"> 43 </span>import qualified Data.Text as T
<span class="lineno"> 44 </span>import qualified Data.Text.Encoding as T
<span class="lineno"> 45 </span>import GHC.Generics (Generic)
<span class="lineno"> 46 </span>import Graphics.SvgTree
<span class="lineno"> 47 </span> ( Tree,
<span class="lineno"> 48 </span> clipPathRef,
<span class="lineno"> 49 </span> clipRule,
<span class="lineno"> 50 </span> mapTree,
<span class="lineno"> 51 </span> parseSvgFile,
<span class="lineno"> 52 </span> strokeColor,
<span class="lineno"> 53 </span> pattern ClipPathTree,
<span class="lineno"> 54 </span> pattern None,
<span class="lineno"> 55 </span> )
<span class="lineno"> 56 </span>import Reanimate.Animation (SVG)
<span class="lineno"> 57 </span>import Reanimate.Cache
<span class="lineno"> 58 </span>import Reanimate.External
<span class="lineno"> 59 </span>import Reanimate.Misc
<span class="lineno"> 60 </span>import Reanimate.Parameters
<span class="lineno"> 61 </span>import Reanimate.Svg
<span class="lineno"> 62 </span>import System.FilePath
<span class="lineno"> 63 </span> ( replaceExtension,
<span class="lineno"> 64 </span> takeFileName,
<span class="lineno"> 65 </span> (&lt;/&gt;),
<span class="lineno"> 66 </span> )
<span class="lineno"> 67 </span>import System.IO.Unsafe (unsafePerformIO)
<span class="lineno"> 68 </span>
<span class="lineno"> 69 </span>-- | TeX backends. They have different features and capabilities.
<span class="lineno"> 70 </span>data TexEngine = LaTeX | XeLaTeX | LuaLaTeX
<span class="lineno"> 71 </span> deriving (Generic, Hashable, <span class="decl"><span class="nottickedoff">Eq</span></span>, <span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff">Ord</span></span></span></span></span></span></span></span></span></span>, <span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff">Read</span></span></span></span></span></span>, <span class="decl"><span class="nottickedoff">Show</span></span>)
<span class="lineno"> 72 </span>
<span class="lineno"> 73 </span>-- | TeX configurations can load packages and set up environments for tex scripts.
<span class="lineno"> 74 </span>data TexConfig = TexConfig
<span class="lineno"> 75 </span> { <span class="nottickedoff"><span class="decl"><span class="nottickedoff">texConfigEngine</span></span></span> :: TexEngine,
<span class="lineno"> 76 </span> <span class="nottickedoff"><span class="decl"><span class="nottickedoff">texConfigHeaders</span></span></span> :: [T.Text],
<span class="lineno"> 77 </span> <span class="nottickedoff"><span class="decl"><span class="nottickedoff">texConfigPostScript</span></span></span> :: [T.Text]
<span class="lineno"> 78 </span> }
<span class="lineno"> 79 </span> deriving (Generic, Hashable, <span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff">Read</span></span></span></span></span></span>, <span class="decl"><span class="nottickedoff">Show</span></span>, <span class="decl"><span class="nottickedoff">Eq</span></span>, <span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff"><span class="decl"><span class="nottickedoff">Ord</span></span></span></span></span></span></span></span></span></span>)
<span class="lineno"> 80 </span>
<span class="lineno"> 81 </span>-- | Render TeX script using a given configuration.
<span class="lineno"> 82 </span>latexCfg :: TexConfig -&gt; T.Text -&gt; SVG
<span class="lineno"> 83 </span><span class="decl"><span class="nottickedoff">latexCfg (TexConfig engine headers postscript) =</span>
<span class="lineno"> 84 </span><span class="spaces"> </span><span class="nottickedoff">gen headers postscript</span>
<span class="lineno"> 85 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 86 </span><span class="spaces"> </span><span class="nottickedoff">gen =</span>
<span class="lineno"> 87 </span><span class="spaces"> </span><span class="nottickedoff">case engine of</span>
<span class="lineno"> 88 </span><span class="spaces"> </span><span class="nottickedoff">LaTeX -&gt; someTexWithHeaders engine &quot;latex&quot; &quot;dvi&quot; []</span>
<span class="lineno"> 89 </span><span class="spaces"> </span><span class="nottickedoff">XeLaTeX -&gt; someTexWithHeaders engine &quot;xelatex&quot; &quot;xdv&quot; [&quot;-no-pdf&quot;]</span>
<span class="lineno"> 90 </span><span class="spaces"> </span><span class="nottickedoff">LuaLaTeX -&gt; someTexWithHeaders engine &quot;lualatex&quot; &quot;pdf&quot; []</span></span>
<span class="lineno"> 91 </span>
<span class="lineno"> 92 </span>-- | Invoke latex and import the result as an SVG object. SVG objects are
<span class="lineno"> 93 </span>-- cached to improve performance.
<span class="lineno"> 94 </span>--
<span class="lineno"> 95 </span>-- Example:
<span class="lineno"> 96 </span>--
<span class="lineno"> 97 </span>-- &gt; latex &quot;$e^{i\\pi}+1=0$&quot;
<span class="lineno"> 98 </span>--
<span class="lineno"> 99 </span>-- &lt;&lt;docs/gifs/doc_latex.gif&gt;&gt;
<span class="lineno"> 100 </span>latex :: T.Text -&gt; Tree
<span class="lineno"> 101 </span><span class="decl"><span class="istickedoff">latex = latexWithHeaders <span class="nottickedoff">[]</span></span></span>
<span class="lineno"> 102 </span>
<span class="lineno"> 103 </span>-- | Invoke latex with extra script headers.
<span class="lineno"> 104 </span>latexWithHeaders :: [T.Text] -&gt; T.Text -&gt; Tree
<span class="lineno"> 105 </span><span class="decl"><span class="istickedoff">latexWithHeaders = someTexWithHeaders <span class="nottickedoff">LaTeX</span> <span class="nottickedoff">&quot;latex&quot;</span> <span class="nottickedoff">&quot;dvi&quot;</span> <span class="nottickedoff">[]</span> <span class="nottickedoff">[]</span></span></span>
<span class="lineno"> 106 </span>
<span class="lineno"> 107 </span>someTexWithHeaders ::
<span class="lineno"> 108 </span> TexEngine -&gt;
<span class="lineno"> 109 </span> String -&gt;
<span class="lineno"> 110 </span> String -&gt;
<span class="lineno"> 111 </span> [String] -&gt;
<span class="lineno"> 112 </span> [T.Text] -&gt;
<span class="lineno"> 113 </span> [T.Text] -&gt;
<span class="lineno"> 114 </span> T.Text -&gt;
<span class="lineno"> 115 </span> Tree
<span class="lineno"> 116 </span><span class="decl"><span class="istickedoff">someTexWithHeaders _engine _exec _dvi _args _headers _postscript tex</span>
<span class="lineno"> 117 </span><span class="spaces"> </span><span class="istickedoff">| <span class="tickonlytrue">pNoExternals</span> = mkText tex</span>
<span class="lineno"> 118 </span><span class="spaces"></span><span class="istickedoff">someTexWithHeaders engine exec dvi args headers postscript tex =</span>
<span class="lineno"> 119 </span><span class="spaces"> </span><span class="istickedoff"><span class="nottickedoff">(unsafePerformIO . (cacheMem . cacheDiskSvg) (latexToSVG engine dvi exec args))</span></span>
<span class="lineno"> 120 </span><span class="spaces"> </span><span class="istickedoff"><span class="nottickedoff">script</span></span>
<span class="lineno"> 121 </span><span class="spaces"> </span><span class="istickedoff">where</span>
<span class="lineno"> 122 </span><span class="spaces"> </span><span class="istickedoff"><span class="nottickedoff">script = mkTexScript exec args headers (T.unlines (postscript ++ [tex]))</span></span></span>
<span class="lineno"> 123 </span>
<span class="lineno"> 124 </span>-- | Invoke latex and separate results.
<span class="lineno"> 125 </span>latexChunks :: [T.Text] -&gt; [Tree]
<span class="lineno"> 126 </span><span class="decl"><span class="nottickedoff">latexChunks chunks | pNoExternals = map mkText chunks</span>
<span class="lineno"> 127 </span><span class="spaces"></span><span class="nottickedoff">latexChunks chunks = worker (svgGlyphs $ latex $ T.concat chunks) chunks</span>
<span class="lineno"> 128 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 129 </span><span class="spaces"> </span><span class="nottickedoff">merge lst = mkGroup [fmt svg | (fmt, _, svg) &lt;- lst]</span>
<span class="lineno"> 130 </span><span class="spaces"> </span><span class="nottickedoff">worker [] [] = []</span>
<span class="lineno"> 131 </span><span class="spaces"> </span><span class="nottickedoff">worker _ [] = error &quot;latex chunk mismatch&quot;</span>
<span class="lineno"> 132 </span><span class="spaces"> </span><span class="nottickedoff">worker everything (x : xs) =</span>
<span class="lineno"> 133 </span><span class="spaces"> </span><span class="nottickedoff">let width = length $ svgGlyphs (latex x)</span>
<span class="lineno"> 134 </span><span class="spaces"> </span><span class="nottickedoff">in merge (take width everything) : worker (drop width everything) xs</span></span>
<span class="lineno"> 135 </span>
<span class="lineno"> 136 </span>-- | Invoke xelatex and import the result as an SVG object. SVG objects are
<span class="lineno"> 137 </span>-- cached to improve performance. Xelatex has support for non-western scripts.
<span class="lineno"> 138 </span>xelatex :: Text -&gt; Tree
<span class="lineno"> 139 </span><span class="decl"><span class="nottickedoff">xelatex = xelatexWithHeaders []</span></span>
<span class="lineno"> 140 </span>
<span class="lineno"> 141 </span>-- | Invoke xelatex with extra script headers.
<span class="lineno"> 142 </span>xelatexWithHeaders :: [T.Text] -&gt; T.Text -&gt; Tree
<span class="lineno"> 143 </span><span class="decl"><span class="nottickedoff">xelatexWithHeaders = someTexWithHeaders XeLaTeX &quot;xelatex&quot; &quot;xdv&quot; [] [&quot;-no-pdf&quot;]</span></span>
<span class="lineno"> 144 </span>
<span class="lineno"> 145 </span>-- | Invoke xelatex with &quot;\usepackage[UTF8]{ctex}&quot; and import the result as an
<span class="lineno"> 146 </span>-- SVG object. SVG objects are cached to improve performance. Xelatex has
<span class="lineno"> 147 </span>-- support for non-western scripts.
<span class="lineno"> 148 </span>--
<span class="lineno"> 149 </span>-- Example:
<span class="lineno"> 150 </span>--
<span class="lineno"> 151 </span>-- &gt; ctex &quot;中文&quot;
<span class="lineno"> 152 </span>--
<span class="lineno"> 153 </span>-- &lt;&lt;docs/gifs/doc_ctex.gif&gt;&gt;
<span class="lineno"> 154 </span>ctex :: T.Text -&gt; Tree
<span class="lineno"> 155 </span><span class="decl"><span class="nottickedoff">ctex = ctexWithHeaders []</span></span>
<span class="lineno"> 156 </span>
<span class="lineno"> 157 </span>-- | Invoke xelatex with extra script headers + ctex headers.
<span class="lineno"> 158 </span>ctexWithHeaders :: [T.Text] -&gt; T.Text -&gt; Tree
<span class="lineno"> 159 </span><span class="decl"><span class="nottickedoff">ctexWithHeaders headers = xelatexWithHeaders (&quot;\\usepackage[UTF8]{ctex}&quot; : headers)</span></span>
<span class="lineno"> 160 </span>
<span class="lineno"> 161 </span>-- | Invoke latex and import the result as an SVG object. SVG objects are
<span class="lineno"> 162 </span>-- cached to improve performance. This wraps the TeX code in an 'align*'
<span class="lineno"> 163 </span>-- context.
<span class="lineno"> 164 </span>--
<span class="lineno"> 165 </span>-- Example:
<span class="lineno"> 166 </span>--
<span class="lineno"> 167 </span>-- &gt; latexAlign &quot;R = \\frac{{\\Delta x}}{{kA}}&quot;
<span class="lineno"> 168 </span>--
<span class="lineno"> 169 </span>-- &lt;&lt;docs/gifs/doc_latexAlign.gif&gt;&gt;
<span class="lineno"> 170 </span>latexAlign :: Text -&gt; Tree
<span class="lineno"> 171 </span><span class="decl"><span class="istickedoff">latexAlign tex = latex $ T.unlines [&quot;\\begin{align*}&quot;, tex, &quot;\\end{align*}&quot;]</span></span>
<span class="lineno"> 172 </span>
<span class="lineno"> 173 </span>postprocess :: Tree -&gt; Tree
<span class="lineno"> 174 </span><span class="decl"><span class="nottickedoff">postprocess =</span>
<span class="lineno"> 175 </span><span class="spaces"> </span><span class="nottickedoff">simplify</span>
<span class="lineno"> 176 </span><span class="spaces"> </span><span class="nottickedoff">. lowerTransformations</span>
<span class="lineno"> 177 </span><span class="spaces"> </span><span class="nottickedoff">. scaleXY 0.1 (-0.1)</span>
<span class="lineno"> 178 </span><span class="spaces"> </span><span class="nottickedoff">. removeClipPaths</span>
<span class="lineno"> 179 </span><span class="spaces"> </span><span class="nottickedoff">. lowerIds</span>
<span class="lineno"> 180 </span><span class="spaces"> </span><span class="nottickedoff">. mapTree clearDrawAttr</span>
<span class="lineno"> 181 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 182 </span><span class="spaces"> </span><span class="nottickedoff">clearDrawAttr t = t &amp; strokeColor .~ Last Nothing</span></span>
<span class="lineno"> 183 </span>
<span class="lineno"> 184 </span>enginePostprocess :: TexEngine -&gt; Tree -&gt; Tree
<span class="lineno"> 185 </span><span class="decl"><span class="nottickedoff">enginePostprocess LuaLaTeX svg = translate 0 (svgHeight svg) svg</span>
<span class="lineno"> 186 </span><span class="spaces"></span><span class="nottickedoff">enginePostprocess _ svg = svg</span></span>
<span class="lineno"> 187 </span>
<span class="lineno"> 188 </span>removeClipPaths :: SVG -&gt; SVG
<span class="lineno"> 189 </span><span class="decl"><span class="nottickedoff">removeClipPaths = mapTree worker</span>
<span class="lineno"> 190 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 191 </span><span class="spaces"> </span><span class="nottickedoff">worker ClipPathTree {} = None</span>
<span class="lineno"> 192 </span><span class="spaces"> </span><span class="nottickedoff">worker t = t &amp; clipRule .~ Last Nothing &amp; clipPathRef .~ Last Nothing</span></span>
<span class="lineno"> 193 </span>
<span class="lineno"> 194 </span>-- executable, arguments, header, tex
<span class="lineno"> 195 </span>latexToSVG :: TexEngine -&gt; String -&gt; String -&gt; [String] -&gt; Text -&gt; IO Tree
<span class="lineno"> 196 </span><span class="decl"><span class="nottickedoff">latexToSVG engine dviExt latexExec latexArgs tex = do</span>
<span class="lineno"> 197 </span><span class="spaces"> </span><span class="nottickedoff">latexBin &lt;- requireExecutable latexExec</span>
<span class="lineno"> 198 </span><span class="spaces"> </span><span class="nottickedoff">withTempDir $ \tmp_dir -&gt; withTempFile &quot;tex&quot; $ \tex_file -&gt;</span>
<span class="lineno"> 199 </span><span class="spaces"> </span><span class="nottickedoff">withTempFile &quot;svg&quot; $ \svg_file -&gt; do</span>
<span class="lineno"> 200 </span><span class="spaces"> </span><span class="nottickedoff">let dvi_file =</span>
<span class="lineno"> 201 </span><span class="spaces"> </span><span class="nottickedoff">tmp_dir &lt;/&gt; replaceExtension (takeFileName tex_file) dviExt</span>
<span class="lineno"> 202 </span><span class="spaces"> </span><span class="nottickedoff">B.writeFile tex_file (T.encodeUtf8 tex)</span>
<span class="lineno"> 203 </span><span class="spaces"> </span><span class="nottickedoff">runCmd</span>
<span class="lineno"> 204 </span><span class="spaces"> </span><span class="nottickedoff">latexBin</span>
<span class="lineno"> 205 </span><span class="spaces"> </span><span class="nottickedoff">( latexArgs</span>
<span class="lineno"> 206 </span><span class="spaces"> </span><span class="nottickedoff">++ [ &quot;-interaction=nonstopmode&quot;,</span>
<span class="lineno"> 207 </span><span class="spaces"> </span><span class="nottickedoff">&quot;-halt-on-error&quot;,</span>
<span class="lineno"> 208 </span><span class="spaces"> </span><span class="nottickedoff">&quot;-output-directory=&quot; ++ tmp_dir,</span>
<span class="lineno"> 209 </span><span class="spaces"> </span><span class="nottickedoff">tex_file</span>
<span class="lineno"> 210 </span><span class="spaces"> </span><span class="nottickedoff">]</span>
<span class="lineno"> 211 </span><span class="spaces"> </span><span class="nottickedoff">)</span>
<span class="lineno"> 212 </span><span class="spaces"> </span><span class="nottickedoff">if dviExt == &quot;pdf&quot;</span>
<span class="lineno"> 213 </span><span class="spaces"> </span><span class="nottickedoff">then do</span>
<span class="lineno"> 214 </span><span class="spaces"> </span><span class="nottickedoff">pdf2svg &lt;- requireExecutable &quot;pdf2svg&quot;</span>
<span class="lineno"> 215 </span><span class="spaces"> </span><span class="nottickedoff">runCmd</span>
<span class="lineno"> 216 </span><span class="spaces"> </span><span class="nottickedoff">pdf2svg</span>
<span class="lineno"> 217 </span><span class="spaces"> </span><span class="nottickedoff">[dvi_file, svg_file]</span>
<span class="lineno"> 218 </span><span class="spaces"> </span><span class="nottickedoff">else do</span>
<span class="lineno"> 219 </span><span class="spaces"> </span><span class="nottickedoff">dvisvgm &lt;- requireExecutable &quot;dvisvgm&quot;</span>
<span class="lineno"> 220 </span><span class="spaces"> </span><span class="nottickedoff">runCmd</span>
<span class="lineno"> 221 </span><span class="spaces"> </span><span class="nottickedoff">dvisvgm</span>
<span class="lineno"> 222 </span><span class="spaces"> </span><span class="nottickedoff">[ dvi_file,</span>
<span class="lineno"> 223 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--precision=5&quot;,</span>
<span class="lineno"> 224 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--exact&quot;, -- better bboxes.</span>
<span class="lineno"> 225 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--no-fonts&quot;, -- use glyphs instead of fonts.</span>
<span class="lineno"> 226 </span><span class="spaces"> </span><span class="nottickedoff">&quot;--verbosity=0&quot;,</span>
<span class="lineno"> 227 </span><span class="spaces"> </span><span class="nottickedoff">&quot;-o&quot;,</span>
<span class="lineno"> 228 </span><span class="spaces"> </span><span class="nottickedoff">svg_file</span>
<span class="lineno"> 229 </span><span class="spaces"> </span><span class="nottickedoff">]</span>
<span class="lineno"> 230 </span><span class="spaces"> </span><span class="nottickedoff">svg_data &lt;- B.readFile svg_file</span>
<span class="lineno"> 231 </span><span class="spaces"> </span><span class="nottickedoff">case parseSvgFile svg_file svg_data of</span>
<span class="lineno"> 232 </span><span class="spaces"> </span><span class="nottickedoff">Nothing -&gt; error &quot;Malformed svg&quot;</span>
<span class="lineno"> 233 </span><span class="spaces"> </span><span class="nottickedoff">Just svg -&gt;</span>
<span class="lineno"> 234 </span><span class="spaces"> </span><span class="nottickedoff">return $</span>
<span class="lineno"> 235 </span><span class="spaces"> </span><span class="nottickedoff">enginePostprocess engine $</span>
<span class="lineno"> 236 </span><span class="spaces"> </span><span class="nottickedoff">postprocess $ unbox $ replaceUses svg</span></span>
<span class="lineno"> 237 </span>
<span class="lineno"> 238 </span>mkTexScript :: String -&gt; [String] -&gt; [Text] -&gt; Text -&gt; Text
<span class="lineno"> 239 </span><span class="decl"><span class="nottickedoff">mkTexScript latexExec latexArgs texHeaders tex =</span>
<span class="lineno"> 240 </span><span class="spaces"> </span><span class="nottickedoff">T.unlines $</span>
<span class="lineno"> 241 </span><span class="spaces"> </span><span class="nottickedoff">[ &quot;% &quot; &lt;&gt; T.pack (unwords (latexExec : latexArgs)),</span>
<span class="lineno"> 242 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\documentclass[preview]{standalone}&quot;,</span>
<span class="lineno"> 243 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\usepackage{amsmath}&quot;,</span>
<span class="lineno"> 244 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\usepackage{gensymb}&quot;</span>
<span class="lineno"> 245 </span><span class="spaces"> </span><span class="nottickedoff">]</span>
<span class="lineno"> 246 </span><span class="spaces"> </span><span class="nottickedoff">++ texHeaders</span>
<span class="lineno"> 247 </span><span class="spaces"> </span><span class="nottickedoff">++ [ &quot;\\usepackage[english]{babel}&quot;,</span>
<span class="lineno"> 248 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\linespread{1}&quot;,</span>
<span class="lineno"> 249 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\begin{document}&quot;,</span>
<span class="lineno"> 250 </span><span class="spaces"> </span><span class="nottickedoff">tex,</span>
<span class="lineno"> 251 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\end{document}&quot;</span>
<span class="lineno"> 252 </span><span class="spaces"> </span><span class="nottickedoff">]</span></span>
<span class="lineno"> 253 </span>
<span class="lineno"> 254 </span>{- Packages used by manim.
<span class="lineno"> 255 </span>
<span class="lineno"> 256 </span>\\\usepackage{amsmath}\n\
<span class="lineno"> 257 </span>\\\usepackage{amssymb}\n\
<span class="lineno"> 258 </span>\\\usepackage{dsfont}\n\
<span class="lineno"> 259 </span>\\\usepackage{setspace}\n\
<span class="lineno"> 260 </span>\\\usepackage{relsize}\n\
<span class="lineno"> 261 </span>\\\usepackage{textcomp}\n\
<span class="lineno"> 262 </span>\\\usepackage{mathrsfs}\n\
<span class="lineno"> 263 </span>\\\usepackage{calligra}\n\
<span class="lineno"> 264 </span>\\\usepackage{wasysym}\n\
<span class="lineno"> 265 </span>\\\usepackage{ragged2e}\n\
<span class="lineno"> 266 </span>\\\usepackage{physics}\n\
<span class="lineno"> 267 </span>\\\usepackage{xcolor}\n\
<span class="lineno"> 268 </span>\\\usepackage{textcomp}\n\
<span class="lineno"> 269 </span>\\\usepackage{xfrac}\n\
<span class="lineno"> 270 </span>\\\usepackage{microtype}\n\
<span class="lineno"> 271 </span>-}
<span class="lineno"> 272 </span>
<span class="lineno"> 273 </span>-- | Chalkduster font. Depends on lualatex.
<span class="lineno"> 274 </span>-- Font files are automatically downloaded.
<span class="lineno"> 275 </span>--
<span class="lineno"> 276 </span>-- @
<span class="lineno"> 277 </span>-- `latexCfg` `chalkduster` &quot;chalkduster&quot;
<span class="lineno"> 278 </span>-- @
<span class="lineno"> 279 </span>--
<span class="lineno"> 280 </span>-- &lt;&lt;docs/gifs/doc_chalkduster.gif&gt;&gt;
<span class="lineno"> 281 </span>chalkduster :: TexConfig
<span class="lineno"> 282 </span><span class="decl"><span class="nottickedoff">chalkduster =</span>
<span class="lineno"> 283 </span><span class="spaces"> </span><span class="nottickedoff">TexConfig</span>
<span class="lineno"> 284 </span><span class="spaces"> </span><span class="nottickedoff">{ texConfigEngine = XeLaTeX,</span>
<span class="lineno"> 285 </span><span class="spaces"> </span><span class="nottickedoff">texConfigHeaders =</span>
<span class="lineno"> 286 </span><span class="spaces"> </span><span class="nottickedoff">[ &quot;\\usepackage[no-math]{fontspec}&quot;,</span>
<span class="lineno"> 287 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\setmainfont[Mapping=tex-text,Path={&quot; &lt;&gt; chalkdusterFont &lt;&gt; &quot;/},Extension=.ttf]{Chalkduster}&quot;,</span>
<span class="lineno"> 288 </span><span class="spaces"> </span><span class="nottickedoff">&quot;\\usepackage[defaultmathsizes]{mathastext}&quot;</span>
<span class="lineno"> 289 </span><span class="spaces"> </span><span class="nottickedoff">],</span>
<span class="lineno"> 290 </span><span class="spaces"> </span><span class="nottickedoff">texConfigPostScript = []</span>
<span class="lineno"> 291 </span><span class="spaces"> </span><span class="nottickedoff">}</span>
<span class="lineno"> 292 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 293 </span><span class="spaces"> </span><span class="nottickedoff">chalkdusterFont =</span>
<span class="lineno"> 294 </span><span class="spaces"> </span><span class="nottickedoff">T.pack $</span>
<span class="lineno"> 295 </span><span class="spaces"> </span><span class="nottickedoff">zipArchive</span>
<span class="lineno"> 296 </span><span class="spaces"> </span><span class="nottickedoff">&quot;https://www.ffonts.net/Chalkduster.font.zip&quot;</span>
<span class="lineno"> 297 </span><span class="spaces"> </span><span class="nottickedoff">&quot;Wplv4RjuFiI0hDQnAM5MVHl2evrZqWstRLdVAfBomCM=&quot;</span></span>
<span class="lineno"> 298 </span>
<span class="lineno"> 299 </span>-- |
<span class="lineno"> 300 </span>-- @
<span class="lineno"> 301 </span>-- `latexCfg` `calligra` &quot;calligra&quot;
<span class="lineno"> 302 </span>-- @
<span class="lineno"> 303 </span>-- `latexCfg` `calligra` &quot;calligra&quot;
<span class="lineno"> 304 </span>-- @
<span class="lineno"> 305 </span>--
<span class="lineno"> 306 </span>-- &lt;&lt;docs/gifs/doc_calligra.gif&gt;&gt;
<span class="lineno"> 307 </span>calligra :: TexConfig
<span class="lineno"> 308 </span><span class="decl"><span class="nottickedoff">calligra =</span>
<span class="lineno"> 309 </span><span class="spaces"> </span><span class="nottickedoff">TexConfig</span>
<span class="lineno"> 310 </span><span class="spaces"> </span><span class="nottickedoff">{ texConfigEngine = LaTeX,</span>
<span class="lineno"> 311 </span><span class="spaces"> </span><span class="nottickedoff">texConfigHeaders = [&quot;\\usepackage{calligra}&quot;],</span>
<span class="lineno"> 312 </span><span class="spaces"> </span><span class="nottickedoff">texConfigPostScript = [&quot;\\calligra&quot;]</span>
<span class="lineno"> 313 </span><span class="spaces"> </span><span class="nottickedoff">}</span></span>
<span class="lineno"> 314 </span>
<span class="lineno"> 315 </span>-- | Noto configuration.
<span class="lineno"> 316 </span>--
<span class="lineno"> 317 </span>-- Example:
<span class="lineno"> 318 </span>--
<span class="lineno"> 319 </span>-- @
<span class="lineno"> 320 </span>-- `latexCfg` `noto` &quot;noto&quot;
<span class="lineno"> 321 </span>-- @
<span class="lineno"> 322 </span>--
<span class="lineno"> 323 </span>-- &lt;&lt;docs/gifs/doc_noto.gif&gt;&gt;
<span class="lineno"> 324 </span>noto :: TexConfig
<span class="lineno"> 325 </span><span class="decl"><span class="nottickedoff">noto =</span>
<span class="lineno"> 326 </span><span class="spaces"> </span><span class="nottickedoff">TexConfig</span>
<span class="lineno"> 327 </span><span class="spaces"> </span><span class="nottickedoff">{ texConfigEngine = LaTeX,</span>
<span class="lineno"> 328 </span><span class="spaces"> </span><span class="nottickedoff">texConfigHeaders = [&quot;\\usepackage{noto}&quot;],</span>
<span class="lineno"> 329 </span><span class="spaces"> </span><span class="nottickedoff">texConfigPostScript = []</span>
<span class="lineno"> 330 </span><span class="spaces"> </span><span class="nottickedoff">}</span></span>
<span class="lineno"> 331 </span>
<span class="lineno"> 332 </span>-- | Helvetica configuration.
<span class="lineno"> 333 </span>--
<span class="lineno"> 334 </span>-- Example:
<span class="lineno"> 335 </span>--
<span class="lineno"> 336 </span>-- @
<span class="lineno"> 337 </span>-- `latexCfg` `helvet` &quot;helvet&quot;
<span class="lineno"> 338 </span>-- @
<span class="lineno"> 339 </span>--
<span class="lineno"> 340 </span>-- &lt;&lt;docs/gifs/doc_helvet.gif&gt;&gt;
<span class="lineno"> 341 </span>helvet :: TexConfig
<span class="lineno"> 342 </span><span class="decl"><span class="nottickedoff">helvet =</span>
<span class="lineno"> 343 </span><span class="spaces"> </span><span class="nottickedoff">TexConfig</span>
<span class="lineno"> 344 </span><span class="spaces"> </span><span class="nottickedoff">{ texConfigEngine = LaTeX,</span>
<span class="lineno"> 345 </span><span class="spaces"> </span><span class="nottickedoff">texConfigHeaders = [&quot;\\usepackage{helvet}&quot;],</span>
<span class="lineno"> 346 </span><span class="spaces"> </span><span class="nottickedoff">texConfigPostScript = []</span>
<span class="lineno"> 347 </span><span class="spaces"> </span><span class="nottickedoff">}</span></span>
<span class="lineno"> 348 </span>
<span class="lineno"> 349 </span>-- | Libertine configuration.
<span class="lineno"> 350 </span>--
<span class="lineno"> 351 </span>-- Example:
<span class="lineno"> 352 </span>--
<span class="lineno"> 353 </span>-- @
<span class="lineno"> 354 </span>-- `latexCfg` `libertine` &quot;libertine&quot;
<span class="lineno"> 355 </span>-- @
<span class="lineno"> 356 </span>--
<span class="lineno"> 357 </span>-- &lt;&lt;docs/gifs/doc_libertine.gif&gt;&gt;
<span class="lineno"> 358 </span>libertine :: TexConfig
<span class="lineno"> 359 </span><span class="decl"><span class="nottickedoff">libertine =</span>
<span class="lineno"> 360 </span><span class="spaces"> </span><span class="nottickedoff">TexConfig</span>
<span class="lineno"> 361 </span><span class="spaces"> </span><span class="nottickedoff">{ texConfigEngine = LaTeX,</span>
<span class="lineno"> 362 </span><span class="spaces"> </span><span class="nottickedoff">texConfigHeaders = [&quot;\\usepackage{libertine}&quot;],</span>
<span class="lineno"> 363 </span><span class="spaces"> </span><span class="nottickedoff">texConfigPostScript = []</span>
<span class="lineno"> 364 </span><span class="spaces"> </span><span class="nottickedoff">}</span></span>
<span class="lineno"> 303 </span>--
<span class="lineno"> 304 </span>-- &lt;&lt;docs/gifs/doc_calligra.gif&gt;&gt;
<span class="lineno"> 305 </span>calligra :: TexConfig
<span class="lineno"> 306 </span><span class="decl"><span class="nottickedoff">calligra =</span>
<span class="lineno"> 307 </span><span class="spaces"> </span><span class="nottickedoff">TexConfig</span>
<span class="lineno"> 308 </span><span class="spaces"> </span><span class="nottickedoff">{ texConfigEngine = LaTeX,</span>
<span class="lineno"> 309 </span><span class="spaces"> </span><span class="nottickedoff">texConfigHeaders = [&quot;\\usepackage{calligra}&quot;],</span>
<span class="lineno"> 310 </span><span class="spaces"> </span><span class="nottickedoff">texConfigPostScript = [&quot;\\calligra&quot;]</span>
<span class="lineno"> 311 </span><span class="spaces"> </span><span class="nottickedoff">}</span></span>
<span class="lineno"> 312 </span>
<span class="lineno"> 313 </span>-- |
<span class="lineno"> 314 </span>-- @
<span class="lineno"> 315 </span>-- `latexCfg` `noto` &quot;noto&quot;
<span class="lineno"> 316 </span>-- @
<span class="lineno"> 317 </span>--
<span class="lineno"> 318 </span>-- &lt;&lt;docs/gifs/doc_noto.gif&gt;&gt;
<span class="lineno"> 319 </span>noto :: TexConfig
<span class="lineno"> 320 </span><span class="decl"><span class="nottickedoff">noto =</span>
<span class="lineno"> 321 </span><span class="spaces"> </span><span class="nottickedoff">TexConfig</span>
<span class="lineno"> 322 </span><span class="spaces"> </span><span class="nottickedoff">{ texConfigEngine = LaTeX,</span>
<span class="lineno"> 323 </span><span class="spaces"> </span><span class="nottickedoff">texConfigHeaders = [&quot;\\usepackage{noto}&quot;],</span>
<span class="lineno"> 324 </span><span class="spaces"> </span><span class="nottickedoff">texConfigPostScript = []</span>
<span class="lineno"> 325 </span><span class="spaces"> </span><span class="nottickedoff">}</span></span>
<span class="lineno"> 326 </span>
<span class="lineno"> 327 </span>-- |
<span class="lineno"> 328 </span>-- @
<span class="lineno"> 329 </span>-- `latexCfg` `helvet` &quot;helvet&quot;
<span class="lineno"> 330 </span>-- @
<span class="lineno"> 331 </span>--
<span class="lineno"> 332 </span>-- &lt;&lt;docs/gifs/doc_helvet.gif&gt;&gt;
<span class="lineno"> 333 </span>helvet :: TexConfig
<span class="lineno"> 334 </span><span class="decl"><span class="nottickedoff">helvet =</span>
<span class="lineno"> 335 </span><span class="spaces"> </span><span class="nottickedoff">TexConfig</span>
<span class="lineno"> 336 </span><span class="spaces"> </span><span class="nottickedoff">{ texConfigEngine = LaTeX,</span>
<span class="lineno"> 337 </span><span class="spaces"> </span><span class="nottickedoff">texConfigHeaders = [&quot;\\usepackage{helvet}&quot;],</span>
<span class="lineno"> 338 </span><span class="spaces"> </span><span class="nottickedoff">texConfigPostScript = []</span>
<span class="lineno"> 339 </span><span class="spaces"> </span><span class="nottickedoff">}</span></span>
<span class="lineno"> 340 </span>
<span class="lineno"> 341 </span>-- |
<span class="lineno"> 342 </span>-- @
<span class="lineno"> 343 </span>-- `latexCfg` `libertine` &quot;libertine&quot;
<span class="lineno"> 344 </span>-- @
<span class="lineno"> 345 </span>--
<span class="lineno"> 346 </span>-- &lt;&lt;docs/gifs/doc_libertine.gif&gt;&gt;
<span class="lineno"> 347 </span>libertine :: TexConfig
<span class="lineno"> 348 </span><span class="decl"><span class="nottickedoff">libertine =</span>
<span class="lineno"> 349 </span><span class="spaces"> </span><span class="nottickedoff">TexConfig</span>
<span class="lineno"> 350 </span><span class="spaces"> </span><span class="nottickedoff">{ texConfigEngine = LaTeX,</span>
<span class="lineno"> 351 </span><span class="spaces"> </span><span class="nottickedoff">texConfigHeaders = [&quot;\\usepackage{libertine}&quot;],</span>
<span class="lineno"> 352 </span><span class="spaces"> </span><span class="nottickedoff">texConfigPostScript = []</span>
<span class="lineno"> 353 </span><span class="spaces"> </span><span class="nottickedoff">}</span></span>
<span class="lineno"> 354 </span>
<span class="lineno"> 355 </span>-- |
<span class="lineno"> 356 </span>-- @
<span class="lineno"> 357 </span>-- `latexCfg` `biolinum` &quot;biolinum&quot;
<span class="lineno"> 358 </span>-- @
<span class="lineno"> 359 </span>--
<span class="lineno"> 360 </span>-- &lt;&lt;docs/gifs/doc_biolinum.gif&gt;&gt;
<span class="lineno"> 361 </span>biolinum :: TexConfig
<span class="lineno"> 362 </span><span class="decl"><span class="nottickedoff">biolinum =</span>
<span class="lineno"> 363 </span><span class="spaces"> </span><span class="nottickedoff">TexConfig</span>
<span class="lineno"> 364 </span><span class="spaces"> </span><span class="nottickedoff">{ texConfigEngine = LaTeX,</span>
<span class="lineno"> 365 </span><span class="spaces"> </span><span class="nottickedoff">texConfigHeaders =</span>
<span class="lineno"> 366 </span><span class="spaces"> </span><span class="nottickedoff">[&quot;\\usepackage{libertine}&quot;</span>
<span class="lineno"> 367 </span><span class="spaces"> </span><span class="nottickedoff">,&quot;\\renewcommand{\\familydefault}{\\sfdefault}&quot;],</span>
<span class="lineno"> 368 </span><span class="spaces"> </span><span class="nottickedoff">texConfigPostScript = []</span>
<span class="lineno"> 369 </span><span class="spaces"> </span><span class="nottickedoff">}</span></span>
<span class="lineno"> 370 </span>
<span class="lineno"> 371 </span>-- |
<span class="lineno"> 372 </span>-- @
<span class="lineno"> 373 </span>-- `latexCfg` `droidSerif` &quot;droidSerif&quot;
<span class="lineno"> 374 </span>-- @
<span class="lineno"> 375 </span>--
<span class="lineno"> 376 </span>-- &lt;&lt;docs/gifs/doc_droidSerif.gif&gt;&gt;
<span class="lineno"> 377 </span>droidSerif :: TexConfig
<span class="lineno"> 378 </span><span class="decl"><span class="nottickedoff">droidSerif =</span>
<span class="lineno"> 379 </span><span class="spaces"> </span><span class="nottickedoff">TexConfig</span>
<span class="lineno"> 380 </span><span class="spaces"> </span><span class="nottickedoff">{ texConfigEngine = LaTeX,</span>
<span class="lineno"> 381 </span><span class="spaces"> </span><span class="nottickedoff">texConfigHeaders =</span>
<span class="lineno"> 382 </span><span class="spaces"> </span><span class="nottickedoff">[&quot;\\usepackage[default]{droidserif}&quot;</span>
<span class="lineno"> 383 </span><span class="spaces"> </span><span class="nottickedoff">,&quot;\\let\\varepsilon\\epsilon&quot;],</span>
<span class="lineno"> 384 </span><span class="spaces"> </span><span class="nottickedoff">texConfigPostScript = []</span>
<span class="lineno"> 385 </span><span class="spaces"> </span><span class="nottickedoff">}</span></span>
<span class="lineno"> 386 </span>
<span class="lineno"> 387 </span>-- |
<span class="lineno"> 388 </span>-- @
<span class="lineno"> 389 </span>-- `latexCfg` `droidSans` &quot;droidSans&quot;
<span class="lineno"> 390 </span>-- @
<span class="lineno"> 391 </span>--
<span class="lineno"> 392 </span>-- &lt;&lt;docs/gifs/doc_droidSans.gif&gt;&gt;
<span class="lineno"> 393 </span>droidSans :: TexConfig
<span class="lineno"> 394 </span><span class="decl"><span class="nottickedoff">droidSans =</span>
<span class="lineno"> 395 </span><span class="spaces"> </span><span class="nottickedoff">TexConfig</span>
<span class="lineno"> 396 </span><span class="spaces"> </span><span class="nottickedoff">{ texConfigEngine = LaTeX,</span>
<span class="lineno"> 397 </span><span class="spaces"> </span><span class="nottickedoff">texConfigHeaders =</span>
<span class="lineno"> 398 </span><span class="spaces"> </span><span class="nottickedoff">[&quot;\\usepackage[default]{droidsans}&quot;</span>
<span class="lineno"> 399 </span><span class="spaces"> </span><span class="nottickedoff">,&quot;\\let\\varepsilon\\epsilon&quot;],</span>
<span class="lineno"> 400 </span><span class="spaces"> </span><span class="nottickedoff">texConfigPostScript = []</span>
<span class="lineno"> 401 </span><span class="spaces"> </span><span class="nottickedoff">}</span></span>
</pre>
</body>

View file

@ -106,7 +106,7 @@ span.spaces { background: white }
<span class="lineno"> 87 </span><span class="spaces"> </span><span class="nottickedoff">Just svg -&gt;</span>
<span class="lineno"> 88 </span><span class="spaces"> </span><span class="nottickedoff">return</span>
<span class="lineno"> 89 </span><span class="spaces"> </span><span class="nottickedoff">$ scaleXY (width / screenWidth) (height / screenHeight)</span>
<span class="lineno"> 90 </span><span class="spaces"> </span><span class="nottickedoff">$ embedDocument svg</span>
<span class="lineno"> 90 </span><span class="spaces"> </span><span class="nottickedoff">$ unboxFit svg</span>
<span class="lineno"> 91 </span><span class="spaces"></span><span class="nottickedoff">mkImage width height path | pRaster == RasterNone = unsafePerformIO $ do</span>
<span class="lineno"> 92 </span><span class="spaces"> </span><span class="nottickedoff">inp &lt;- LBS.readFile path</span>
<span class="lineno"> 93 </span><span class="spaces"> </span><span class="nottickedoff">let imgData = LBS.unpack $ Base64.encode inp</span>

View file

@ -27,71 +27,88 @@ span.spaces { background: white }
<span class="lineno"> 8 </span>module Reanimate.Svg.Unuse
<span class="lineno"> 9 </span> ( replaceUses
<span class="lineno"> 10 </span> , unbox
<span class="lineno"> 11 </span> , embedDocument
<span class="lineno"> 12 </span> ) where
<span class="lineno"> 13 </span>
<span class="lineno"> 14 </span>import Control.Lens ((%~), (&amp;), (.~), (?~), (^.))
<span class="lineno"> 15 </span>import qualified Data.Map as Map
<span class="lineno"> 16 </span>import Data.Maybe
<span class="lineno"> 17 </span>import Graphics.SvgTree
<span class="lineno"> 18 </span>import Reanimate.Constants
<span class="lineno"> 19 </span>import Reanimate.Svg.Constructors
<span class="lineno"> 20 </span>
<span class="lineno"> 21 </span>-- | Replace all @&lt;use&gt;@ nodes with their definition.
<span class="lineno"> 22 </span>replaceUses :: Document -&gt; Document
<span class="lineno"> 23 </span><span class="decl"><span class="nottickedoff">replaceUses doc = doc &amp; documentElements %~ map (mapTree replace)</span>
<span class="lineno"> 24 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 25 </span><span class="spaces"> </span><span class="nottickedoff">replaceDefinition PathTree{} = None</span>
<span class="lineno"> 26 </span><span class="spaces"> </span><span class="nottickedoff">replaceDefinition SymbolTree{} = None</span>
<span class="lineno"> 27 </span><span class="spaces"> </span><span class="nottickedoff">replaceDefinition t = t</span>
<span class="lineno"> 28 </span><span class="spaces"></span><span class="nottickedoff"></span>
<span class="lineno"> 29 </span><span class="spaces"> </span><span class="nottickedoff">replace t@DefinitionTree{} = mapTree replaceDefinition t</span>
<span class="lineno"> 30 </span><span class="spaces"> </span><span class="nottickedoff">replace (UseTree _ Just{}) = error &quot;replaceUses: subtree in use?&quot;</span>
<span class="lineno"> 31 </span><span class="spaces"> </span><span class="nottickedoff">replace (UseTree use Nothing) =</span>
<span class="lineno"> 32 </span><span class="spaces"> </span><span class="nottickedoff">case Map.lookup (use^.useName) idMap of</span>
<span class="lineno"> 33 </span><span class="spaces"> </span><span class="nottickedoff">Nothing -&gt; error $ &quot;Unknown id: &quot; ++ (use^.useName)</span>
<span class="lineno"> 34 </span><span class="spaces"> </span><span class="nottickedoff">Just (SymbolTree children) -&gt; mapTree replace $</span>
<span class="lineno"> 35 </span><span class="spaces"> </span><span class="nottickedoff">GroupTree children</span>
<span class="lineno"> 36 </span><span class="spaces"> </span><span class="nottickedoff">&amp; transform ?~</span>
<span class="lineno"> 37 </span><span class="spaces"> </span><span class="nottickedoff">fromMaybe [] (use^.transform) ++</span>
<span class="lineno"> 38 </span><span class="spaces"> </span><span class="nottickedoff">[baseToTransformation (use^.useBase)]</span>
<span class="lineno"> 39 </span><span class="spaces"> </span><span class="nottickedoff">Just tree -&gt; mapTree replace $</span>
<span class="lineno"> 40 </span><span class="spaces"> </span><span class="nottickedoff">GroupTree (defaultSvg &amp; groupChildren .~ [tree])</span>
<span class="lineno"> 41 </span><span class="spaces"> </span><span class="nottickedoff">&amp; transform ?~</span>
<span class="lineno"> 42 </span><span class="spaces"> </span><span class="nottickedoff">fromMaybe [] (use^.transform) ++</span>
<span class="lineno"> 43 </span><span class="spaces"> </span><span class="nottickedoff">[baseToTransformation (use^.useBase)]</span>
<span class="lineno"> 44 </span><span class="spaces"> </span><span class="nottickedoff">replace x = x</span>
<span class="lineno"> 45 </span><span class="spaces"> </span><span class="nottickedoff">baseToTransformation (x,y) =</span>
<span class="lineno"> 46 </span><span class="spaces"> </span><span class="nottickedoff">case (toUserUnit defaultDPI x, toUserUnit defaultDPI y) of</span>
<span class="lineno"> 47 </span><span class="spaces"> </span><span class="nottickedoff">(Num a, Num b) -&gt; Translate a b</span>
<span class="lineno"> 48 </span><span class="spaces"> </span><span class="nottickedoff">_ -&gt; TransformUnknown</span>
<span class="lineno"> 49 </span><span class="spaces"> </span><span class="nottickedoff">docTree = mkGroup (doc^.documentElements)</span>
<span class="lineno"> 50 </span><span class="spaces"> </span><span class="nottickedoff">idMap = foldTree updMap Map.empty docTree</span>
<span class="lineno"> 51 </span><span class="spaces"> </span><span class="nottickedoff">updMap m tree =</span>
<span class="lineno"> 52 </span><span class="spaces"> </span><span class="nottickedoff">case tree^.attrId of</span>
<span class="lineno"> 53 </span><span class="spaces"> </span><span class="nottickedoff">Nothing -&gt; m</span>
<span class="lineno"> 54 </span><span class="spaces"> </span><span class="nottickedoff">Just tid -&gt; Map.insert tid tree m</span></span>
<span class="lineno"> 55 </span>
<span class="lineno"> 56 </span>-- FIXME: the viewbox is ignored. Can we use the viewbox as a mask?
<span class="lineno"> 57 </span>-- | Transform out viewbox. Definitions and CSS rules are discarded.
<span class="lineno"> 58 </span>unbox :: Document -&gt; Tree
<span class="lineno"> 59 </span><span class="decl"><span class="nottickedoff">unbox doc@Document{_documentViewBox = Just (_minx, _minw, _width, _height)} =</span>
<span class="lineno"> 60 </span><span class="spaces"> </span><span class="nottickedoff">groupTree $ defaultSvg</span>
<span class="lineno"> 61 </span><span class="spaces"> </span><span class="nottickedoff">&amp; groupChildren .~ doc^.documentElements</span>
<span class="lineno"> 62 </span><span class="spaces"></span><span class="nottickedoff">unbox doc =</span>
<span class="lineno"> 63 </span><span class="spaces"> </span><span class="nottickedoff">groupTree $ defaultSvg</span>
<span class="lineno"> 64 </span><span class="spaces"> </span><span class="nottickedoff">&amp; groupChildren .~ doc^.documentElements</span></span>
<span class="lineno"> 65 </span>
<span class="lineno"> 66 </span>-- | Embed 'Document'. This keeps the entire document intact but makes
<span class="lineno"> 67 </span>-- it more difficult to use, say, `Reanimate.Svg.pathify` on it.
<span class="lineno"> 68 </span>embedDocument :: Document -&gt; Tree
<span class="lineno"> 69 </span><span class="decl"><span class="istickedoff">embedDocument doc =</span>
<span class="lineno"> 70 </span><span class="spaces"> </span><span class="istickedoff">translate (-screenWidth/2) (screenHeight/2) $</span>
<span class="lineno"> 71 </span><span class="spaces"> </span><span class="istickedoff">withFillOpacity 1 $</span>
<span class="lineno"> 72 </span><span class="spaces"> </span><span class="istickedoff">withStrokeWidth 0 $</span>
<span class="lineno"> 73 </span><span class="spaces"> </span><span class="istickedoff">flipYAxis $</span>
<span class="lineno"> 74 </span><span class="spaces"> </span><span class="istickedoff">svgTree $ doc &amp; documentWidth .~ Nothing</span>
<span class="lineno"> 75 </span><span class="spaces"> </span><span class="istickedoff">&amp; documentHeight .~ Nothing</span></span>
<span class="lineno"> 11 </span> , unboxFit
<span class="lineno"> 12 </span> , embedDocument
<span class="lineno"> 13 </span> ) where
<span class="lineno"> 14 </span>
<span class="lineno"> 15 </span>import Control.Lens ((%~), (&amp;), (.~), (?~), (^.))
<span class="lineno"> 16 </span>import qualified Data.Map as Map
<span class="lineno"> 17 </span>import Data.Maybe
<span class="lineno"> 18 </span>import Graphics.SvgTree
<span class="lineno"> 19 </span>import Reanimate.Constants
<span class="lineno"> 20 </span>import Reanimate.Svg.Constructors
<span class="lineno"> 21 </span>
<span class="lineno"> 22 </span>-- | Replace all @&lt;use&gt;@ nodes with their definition.
<span class="lineno"> 23 </span>replaceUses :: Document -&gt; Document
<span class="lineno"> 24 </span><span class="decl"><span class="nottickedoff">replaceUses doc = doc &amp; documentElements %~ map (mapTree replace)</span>
<span class="lineno"> 25 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 26 </span><span class="spaces"> </span><span class="nottickedoff">replaceDefinition PathTree{} = None</span>
<span class="lineno"> 27 </span><span class="spaces"> </span><span class="nottickedoff">replaceDefinition SymbolTree{} = None</span>
<span class="lineno"> 28 </span><span class="spaces"> </span><span class="nottickedoff">replaceDefinition t = t</span>
<span class="lineno"> 29 </span><span class="spaces"></span><span class="nottickedoff"></span>
<span class="lineno"> 30 </span><span class="spaces"> </span><span class="nottickedoff">replace t@DefinitionTree{} = mapTree replaceDefinition t</span>
<span class="lineno"> 31 </span><span class="spaces"> </span><span class="nottickedoff">replace (UseTree _ Just{}) = error &quot;replaceUses: subtree in use?&quot;</span>
<span class="lineno"> 32 </span><span class="spaces"> </span><span class="nottickedoff">replace (UseTree use Nothing) =</span>
<span class="lineno"> 33 </span><span class="spaces"> </span><span class="nottickedoff">case Map.lookup (use^.useName) idMap of</span>
<span class="lineno"> 34 </span><span class="spaces"> </span><span class="nottickedoff">Nothing -&gt; error $ &quot;Unknown id: &quot; ++ (use^.useName)</span>
<span class="lineno"> 35 </span><span class="spaces"> </span><span class="nottickedoff">Just (SymbolTree children) -&gt; mapTree replace $</span>
<span class="lineno"> 36 </span><span class="spaces"> </span><span class="nottickedoff">GroupTree children</span>
<span class="lineno"> 37 </span><span class="spaces"> </span><span class="nottickedoff">&amp; transform ?~</span>
<span class="lineno"> 38 </span><span class="spaces"> </span><span class="nottickedoff">fromMaybe [] (use^.transform) ++</span>
<span class="lineno"> 39 </span><span class="spaces"> </span><span class="nottickedoff">[baseToTransformation (use^.useBase)]</span>
<span class="lineno"> 40 </span><span class="spaces"> </span><span class="nottickedoff">Just tree -&gt; mapTree replace $</span>
<span class="lineno"> 41 </span><span class="spaces"> </span><span class="nottickedoff">GroupTree (defaultSvg &amp; groupChildren .~ [tree])</span>
<span class="lineno"> 42 </span><span class="spaces"> </span><span class="nottickedoff">&amp; transform ?~</span>
<span class="lineno"> 43 </span><span class="spaces"> </span><span class="nottickedoff">fromMaybe [] (use^.transform) ++</span>
<span class="lineno"> 44 </span><span class="spaces"> </span><span class="nottickedoff">[baseToTransformation (use^.useBase)]</span>
<span class="lineno"> 45 </span><span class="spaces"> </span><span class="nottickedoff">replace x = x</span>
<span class="lineno"> 46 </span><span class="spaces"> </span><span class="nottickedoff">baseToTransformation (x,y) =</span>
<span class="lineno"> 47 </span><span class="spaces"> </span><span class="nottickedoff">case (toUserUnit defaultDPI x, toUserUnit defaultDPI y) of</span>
<span class="lineno"> 48 </span><span class="spaces"> </span><span class="nottickedoff">(Num a, Num b) -&gt; Translate a b</span>
<span class="lineno"> 49 </span><span class="spaces"> </span><span class="nottickedoff">_ -&gt; TransformUnknown</span>
<span class="lineno"> 50 </span><span class="spaces"> </span><span class="nottickedoff">docTree = mkGroup (doc^.documentElements)</span>
<span class="lineno"> 51 </span><span class="spaces"> </span><span class="nottickedoff">idMap = foldTree updMap Map.empty docTree</span>
<span class="lineno"> 52 </span><span class="spaces"> </span><span class="nottickedoff">updMap m tree =</span>
<span class="lineno"> 53 </span><span class="spaces"> </span><span class="nottickedoff">case tree^.attrId of</span>
<span class="lineno"> 54 </span><span class="spaces"> </span><span class="nottickedoff">Nothing -&gt; m</span>
<span class="lineno"> 55 </span><span class="spaces"> </span><span class="nottickedoff">Just tid -&gt; Map.insert tid tree m</span></span>
<span class="lineno"> 56 </span>
<span class="lineno"> 57 </span>-- FIXME: the viewbox is ignored. Can we use the viewbox as a mask?
<span class="lineno"> 58 </span>-- | Transform out viewbox. Definitions and CSS rules are discarded.
<span class="lineno"> 59 </span>unbox :: Document -&gt; Tree
<span class="lineno"> 60 </span><span class="decl"><span class="nottickedoff">unbox doc@Document{_documentViewBox = Just (_minx, _miny, _width, _height)} =</span>
<span class="lineno"> 61 </span><span class="spaces"> </span><span class="nottickedoff">groupTree $ defaultSvg</span>
<span class="lineno"> 62 </span><span class="spaces"> </span><span class="nottickedoff">&amp; groupChildren .~ doc^.documentElements</span>
<span class="lineno"> 63 </span><span class="spaces"></span><span class="nottickedoff">unbox doc =</span>
<span class="lineno"> 64 </span><span class="spaces"> </span><span class="nottickedoff">groupTree $ defaultSvg</span>
<span class="lineno"> 65 </span><span class="spaces"> </span><span class="nottickedoff">&amp; groupChildren .~ doc^.documentElements</span></span>
<span class="lineno"> 66 </span>
<span class="lineno"> 67 </span>-- | Transform out viewbox and fit image to screen size.
<span class="lineno"> 68 </span>unboxFit :: Document -&gt; Tree
<span class="lineno"> 69 </span><span class="decl"><span class="nottickedoff">unboxFit doc@Document{_documentViewBox = Just (minx, miny, width, height)} =</span>
<span class="lineno"> 70 </span><span class="spaces"> </span><span class="nottickedoff">let widthScale = screenWidth/width</span>
<span class="lineno"> 71 </span><span class="spaces"> </span><span class="nottickedoff">heightScale = screenHeight/height</span>
<span class="lineno"> 72 </span><span class="spaces"> </span><span class="nottickedoff">scaler = min widthScale heightScale</span>
<span class="lineno"> 73 </span><span class="spaces"> </span><span class="nottickedoff">in</span>
<span class="lineno"> 74 </span><span class="spaces"> </span><span class="nottickedoff">scaleXY scaler (-scaler) $</span>
<span class="lineno"> 75 </span><span class="spaces"> </span><span class="nottickedoff">translate (-minx-width/2) (-miny-height/2) $</span>
<span class="lineno"> 76 </span><span class="spaces"> </span><span class="nottickedoff">groupTree $ defaultSvg</span>
<span class="lineno"> 77 </span><span class="spaces"> </span><span class="nottickedoff">&amp; groupChildren .~ doc^.documentElements</span>
<span class="lineno"> 78 </span><span class="spaces"></span><span class="nottickedoff">unboxFit doc =</span>
<span class="lineno"> 79 </span><span class="spaces"> </span><span class="nottickedoff">groupTree $ defaultSvg</span>
<span class="lineno"> 80 </span><span class="spaces"> </span><span class="nottickedoff">&amp; groupChildren .~ doc^.documentElements</span></span>
<span class="lineno"> 81 </span>
<span class="lineno"> 82 </span>
<span class="lineno"> 83 </span>-- | Embed 'Document'. This keeps the entire document intact but makes
<span class="lineno"> 84 </span>-- it more difficult to use, say, `Reanimate.Svg.pathify` on it.
<span class="lineno"> 85 </span>embedDocument :: Document -&gt; Tree
<span class="lineno"> 86 </span><span class="decl"><span class="istickedoff">embedDocument doc =</span>
<span class="lineno"> 87 </span><span class="spaces"> </span><span class="istickedoff">translate (-screenWidth/2) (screenHeight/2) $</span>
<span class="lineno"> 88 </span><span class="spaces"> </span><span class="istickedoff">withFillOpacity 1 $</span>
<span class="lineno"> 89 </span><span class="spaces"> </span><span class="istickedoff">withStrokeWidth 0 $</span>
<span class="lineno"> 90 </span><span class="spaces"> </span><span class="istickedoff">flipYAxis $</span>
<span class="lineno"> 91 </span><span class="spaces"> </span><span class="istickedoff">svgTree $ doc &amp; documentWidth .~ Nothing</span>
<span class="lineno"> 92 </span><span class="spaces"> </span><span class="istickedoff">&amp; documentHeight .~ Nothing</span></span>
</pre>
</body>