@pretextbook/pretext-html 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -3
- package/assets/preview-html.xsl +230 -230
- package/assets/upstream.json +7 -7
- package/assets/xsl/README.md +0 -0
- package/assets/xsl/entities.ent +154 -154
- package/assets/xsl/extract-asymptote.xsl +68 -68
- package/assets/xsl/extract-biblio-csl.xsl +327 -327
- package/assets/xsl/extract-datafile.xsl +71 -71
- package/assets/xsl/extract-dynamic.xsl +139 -139
- package/assets/xsl/extract-identity.xsl +136 -136
- package/assets/xsl/extract-interactive.xsl +81 -81
- package/assets/xsl/extract-latex-image.xsl +118 -118
- package/assets/xsl/extract-mermaid.xsl +58 -58
- package/assets/xsl/extract-mom.xsl +63 -63
- package/assets/xsl/extract-pg.xsl +2897 -2897
- package/assets/xsl/extract-prefigure.xsl +157 -157
- package/assets/xsl/extract-qrcode.xsl +100 -100
- package/assets/xsl/extract-runestone-page-template.xsl +139 -139
- package/assets/xsl/extract-sageplot.xsl +166 -166
- package/assets/xsl/extract-stack.xsl +56 -56
- package/assets/xsl/extract-trace.xsl +134 -134
- package/assets/xsl/extract-youtube.xsl +63 -63
- package/assets/xsl/html-symbols.xsl +3344 -3344
- package/assets/xsl/latex/pretext-latex-AIM.xsl +56 -56
- package/assets/xsl/latex/pretext-latex-CLP.xsl +148 -148
- package/assets/xsl/latex/pretext-latex-chaos.xsl +317 -317
- package/assets/xsl/latex/pretext-latex-dyslexic-font.xsl +76 -76
- package/assets/xsl/latex/pretext-latex-guide.xsl +104 -104
- package/assets/xsl/latex/pretext-latex-texstyle.xsl +862 -862
- package/assets/xsl/localizations/README.md +0 -0
- package/assets/xsl/localizations/af-ZA.xml +276 -276
- package/assets/xsl/localizations/bg-BG.xml +276 -276
- package/assets/xsl/localizations/ca-ES.xml +285 -285
- package/assets/xsl/localizations/cs-CZ.xml +280 -280
- package/assets/xsl/localizations/de-DE.xml +281 -281
- package/assets/xsl/localizations/en-US.xml +427 -427
- package/assets/xsl/localizations/es-ES.xml +287 -287
- package/assets/xsl/localizations/fi-FI.xml +275 -275
- package/assets/xsl/localizations/fr-CA.xml +276 -276
- package/assets/xsl/localizations/fr-FR.xml +280 -280
- package/assets/xsl/localizations/hu-HU.xml +280 -280
- package/assets/xsl/localizations/it-IT.xml +276 -276
- package/assets/xsl/localizations/ku-CKB.xml +275 -275
- package/assets/xsl/localizations/localizations.xml +48 -48
- package/assets/xsl/localizations/nl-NL.xml +275 -275
- package/assets/xsl/localizations/pt-BR.xml +288 -288
- package/assets/xsl/localizations/pt-PT.xml +292 -292
- package/assets/xsl/localizations/zh-HANS.xml +269 -269
- package/assets/xsl/pretext-assembly.xsl +4795 -4795
- package/assets/xsl/pretext-basic-html.xsl +86 -86
- package/assets/xsl/pretext-beamer.xsl +662 -662
- package/assets/xsl/pretext-braille-preprint.xsl +2249 -2249
- package/assets/xsl/pretext-common.xsl +12018 -12018
- package/assets/xsl/pretext-dynamic.xsl +65 -65
- package/assets/xsl/pretext-epub.xsl +1483 -1483
- package/assets/xsl/pretext-fo.xsl +4593 -4593
- package/assets/xsl/pretext-html.xsl +14791 -14791
- package/assets/xsl/pretext-json-manifest.xsl +150 -150
- package/assets/xsl/pretext-jupyter.xsl +868 -868
- package/assets/xsl/pretext-latex-classic.xsl +952 -952
- package/assets/xsl/pretext-latex-common.xsl +11563 -11563
- package/assets/xsl/pretext-latex.xsl +47 -47
- package/assets/xsl/pretext-litprog.xsl +105 -105
- package/assets/xsl/pretext-merge.xsl +41 -41
- package/assets/xsl/pretext-numbers.xsl +875 -875
- package/assets/xsl/pretext-revealjs.xsl +522 -522
- package/assets/xsl/pretext-runestone-fitb.xsl +1233 -1233
- package/assets/xsl/pretext-runestone-static.xsl +1438 -1438
- package/assets/xsl/pretext-runestone.xsl +3083 -3083
- package/assets/xsl/pretext-sage-doctest.xsl +289 -289
- package/assets/xsl/pretext-smc.xsl +492 -492
- package/assets/xsl/pretext-solution-manual-latex.xsl +323 -323
- package/assets/xsl/pretext-text-utilities.xsl +1217 -1217
- package/assets/xsl/pretext-text.xsl +392 -392
- package/assets/xsl/pretext-units.xsl +195 -195
- package/assets/xsl/pretext-view-source.xsl +157 -157
- package/assets/xsl/pretext-ww-problem-sets.xsl +391 -391
- package/assets/xsl/publisher-variables.xsl +4756 -4756
- package/assets/xsl/support/README.md +0 -0
- package/assets/xsl/support/extract-math.xsl +256 -256
- package/assets/xsl/support/package-math.xsl +141 -141
- package/assets/xsl/support/play-button/README.md +0 -0
- package/assets/xsl/support/play-button/play-button.png +0 -0
- package/assets/xsl/support/play-button/play-button.svg +3 -3
- package/assets/xsl/support/pretext-pg-macros.xsl +110 -110
- package/assets/xsl/support/webpack_static_imports.xml +14 -14
- package/assets/xsl/tests/README.md +0 -0
- package/assets/xsl/tests/null.xml +3 -3
- package/assets/xsl/tests/pretext-text-utilities-test.xsl +333 -333
- package/assets/xsl/utilities/README.md +0 -0
- package/assets/xsl/utilities/author-report.xsl +107 -107
- package/assets/xsl/utilities/deprecate-autoname.sed +18 -18
- package/assets/xsl/utilities/deprecate-index.sed +33 -33
- package/assets/xsl/utilities/fix-deprecations.xsl +663 -663
- package/assets/xsl/utilities/pretext-enhanced-source.xsl +112 -112
- package/assets/xsl/utilities/report-publisher-variables.xsl +162 -162
- package/assets/xsl/xml-to-json.xsl +326 -326
- package/assets/xsl/xml-to-string.xsl +328 -328
- package/dist/{cli-C6tfAVvi.js → cli-BQizBK0N.js} +74 -72
- package/dist/cli.d.ts +0 -0
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +12 -6
- package/dist/mounts.d.ts +0 -0
- package/dist/publication.d.ts +0 -0
- package/dist/renderer.d.ts +10 -0
- package/dist/sourcemap.d.ts +0 -0
- package/dist/theme.d.ts +68 -0
- package/dist/theme.js +93 -0
- package/dist/xinclude.d.ts +0 -0
- package/package.json +14 -2
|
@@ -1,1438 +1,1438 @@
|
|
|
1
|
-
<?xml version='1.0'?> <!-- As XML file -->
|
|
2
|
-
|
|
3
|
-
<!--********************************************************************
|
|
4
|
-
Copyright 2022 Robert A. Beezer
|
|
5
|
-
|
|
6
|
-
This file is part of PreTeXt.
|
|
7
|
-
|
|
8
|
-
PreTeXt is free software: you can redistribute it and/or modify
|
|
9
|
-
it under the terms of the GNU General Public License as published by
|
|
10
|
-
the Free Software Foundation, either version 2 or version 3 of the
|
|
11
|
-
License (at your option).
|
|
12
|
-
|
|
13
|
-
PreTeXt is distributed in the hope that it will be useful,
|
|
14
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
-
GNU General Public License for more details.
|
|
17
|
-
|
|
18
|
-
You should have received a copy of the GNU General Public License
|
|
19
|
-
along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
-
*********************************************************************-->
|
|
21
|
-
|
|
22
|
-
<!-- http://pimpmyxslt.com/articles/entity-tricks-part2/ -->
|
|
23
|
-
<!DOCTYPE xsl:stylesheet [
|
|
24
|
-
<!ENTITY % entities SYSTEM "entities.ent">
|
|
25
|
-
%entities;
|
|
26
|
-
]>
|
|
27
|
-
|
|
28
|
-
<xsl:stylesheet
|
|
29
|
-
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
|
|
30
|
-
xmlns:xml="http://www.w3.org/XML/1998/namespace"
|
|
31
|
-
xmlns:pi="http://pretextbook.org/2020/pretext/internal"
|
|
32
|
-
xmlns:exsl="http://exslt.org/common"
|
|
33
|
-
xmlns:str="http://exslt.org/strings"
|
|
34
|
-
extension-element-prefixes="pi exsl str"
|
|
35
|
-
>
|
|
36
|
-
|
|
37
|
-
<!-- Conversion of author source for Runestone/interactive exercises -->
|
|
38
|
-
<!-- to "standard" PreTeXt exercises, which can be used as-is in -->
|
|
39
|
-
<!-- *every* conversion, except the HTML conversion, where a more -->
|
|
40
|
-
<!-- capable version is designed to be powered by Runestone Services. -->
|
|
41
|
-
|
|
42
|
-
<!-- We include text utilities so we can manipulate indentation -->
|
|
43
|
-
<!-- in blocks of code as part of Parsons problems -->
|
|
44
|
-
<xsl:include href = "./pretext-text-utilities.xsl"/>
|
|
45
|
-
|
|
46
|
-
<!-- The enclosing "exercise" and its attributes are preserved -->
|
|
47
|
-
<!-- before these templates are applied, so these should just -->
|
|
48
|
-
<!-- produce the "body" of the exercise. -->
|
|
49
|
-
|
|
50
|
-
<!-- The application of the "runestone-to-static" template is -->
|
|
51
|
-
<!-- controlled by a surrounding "match" that limits elements -->
|
|
52
|
-
<!-- to "exercise", PROJECT-LIKE, and soon "task". So the -->
|
|
53
|
-
<!-- matches here are fine with a *[@exercise-interactive='foo'], -->
|
|
54
|
-
<!-- as a convenience. -->
|
|
55
|
-
|
|
56
|
-
<!-- These get-programming-language templates duplicate logic from pretext-common -->
|
|
57
|
-
<!-- as the contents of that file are not available yet. -->
|
|
58
|
-
<xsl:template match="program" mode="get-programming-language">
|
|
59
|
-
<xsl:choose>
|
|
60
|
-
<xsl:when test="@language">
|
|
61
|
-
<xsl:value-of select="@language" />
|
|
62
|
-
</xsl:when>
|
|
63
|
-
<xsl:when test="$version-docinfo/programs/@language">
|
|
64
|
-
<xsl:value-of select="$version-docinfo/programs/@language" />
|
|
65
|
-
</xsl:when>
|
|
66
|
-
</xsl:choose>
|
|
67
|
-
</xsl:template>
|
|
68
|
-
|
|
69
|
-
<xsl:template match="*[@exercise-interactive = 'parson' or @exercise-interactive = 'parson-horizontal']" mode="get-programming-language">
|
|
70
|
-
<xsl:choose>
|
|
71
|
-
<xsl:when test="@language">
|
|
72
|
-
<xsl:value-of select="@language" />
|
|
73
|
-
</xsl:when>
|
|
74
|
-
<xsl:when test="$version-docinfo/parsons/@language">
|
|
75
|
-
<xsl:value-of select="$version-docinfo/parsons/@language" />
|
|
76
|
-
</xsl:when>
|
|
77
|
-
<xsl:when test="$version-docinfo/programs/@language">
|
|
78
|
-
<xsl:value-of select="$version-docinfo/programs/@language" />
|
|
79
|
-
</xsl:when>
|
|
80
|
-
</xsl:choose>
|
|
81
|
-
</xsl:template>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
<!-- True/False -->
|
|
85
|
-
|
|
86
|
-
<xsl:template match="*[@exercise-interactive = 'truefalse']" mode="runestone-to-static">
|
|
87
|
-
<!-- metadata (idx, title) -->
|
|
88
|
-
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
89
|
-
<!-- prompt, followed by ordered list of choices -->
|
|
90
|
-
<statement>
|
|
91
|
-
<xsl:copy-of select="statement/node()"/>
|
|
92
|
-
</statement>
|
|
93
|
-
<!-- Hints are authored, not derived from problem formulation -->
|
|
94
|
-
<xsl:copy-of select="hint"/>
|
|
95
|
-
<!-- Any authored answers, not derived from problem formulation. -->
|
|
96
|
-
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
97
|
-
<!-- versions on authored ones. -->
|
|
98
|
-
<xsl:copy-of select="answer"/>
|
|
99
|
-
<!-- the answer, simply "True" or "False" -->
|
|
100
|
-
<answer>
|
|
101
|
-
<xsl:choose>
|
|
102
|
-
<xsl:when test="statement/@correct = 'yes'">
|
|
103
|
-
<p>
|
|
104
|
-
<xsl:element name="pi:localize">
|
|
105
|
-
<xsl:attribute name="string-id">true</xsl:attribute>
|
|
106
|
-
</xsl:element>
|
|
107
|
-
<xsl:text>.</xsl:text>
|
|
108
|
-
</p>
|
|
109
|
-
</xsl:when>
|
|
110
|
-
<xsl:when test="statement/@correct = 'no'">
|
|
111
|
-
<p>
|
|
112
|
-
<xsl:element name="pi:localize">
|
|
113
|
-
<xsl:attribute name="string-id">false</xsl:attribute>
|
|
114
|
-
</xsl:element>
|
|
115
|
-
<xsl:text>.</xsl:text>
|
|
116
|
-
</p>
|
|
117
|
-
</xsl:when>
|
|
118
|
-
<xsl:otherwise/>
|
|
119
|
-
</xsl:choose>
|
|
120
|
-
</answer>
|
|
121
|
-
<!-- Any authored solutions, not derived from problem formulation. -->
|
|
122
|
-
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
123
|
-
<!-- versions on authored ones. -->
|
|
124
|
-
<xsl:copy-of select="solution"/>
|
|
125
|
-
<!-- Answer, as above, plus explication with feedback -->
|
|
126
|
-
<!-- TODO: experiment with a one-item "dl" for a slightly more -->
|
|
127
|
-
<!-- appealing presentation, rather than a one-word paragraph. -->
|
|
128
|
-
<solution>
|
|
129
|
-
<xsl:choose>
|
|
130
|
-
<xsl:when test="statement/@correct = 'yes'">
|
|
131
|
-
<p>
|
|
132
|
-
<xsl:element name="pi:localize">
|
|
133
|
-
<xsl:attribute name="string-id">true</xsl:attribute>
|
|
134
|
-
</xsl:element>
|
|
135
|
-
<xsl:text>.</xsl:text>
|
|
136
|
-
</p>
|
|
137
|
-
</xsl:when>
|
|
138
|
-
<xsl:when test="statement/@correct = 'no'">
|
|
139
|
-
<p>
|
|
140
|
-
<xsl:element name="pi:localize">
|
|
141
|
-
<xsl:attribute name="string-id">false</xsl:attribute>
|
|
142
|
-
</xsl:element>
|
|
143
|
-
<xsl:text>.</xsl:text>
|
|
144
|
-
</p>
|
|
145
|
-
</xsl:when>
|
|
146
|
-
<xsl:otherwise/>
|
|
147
|
-
</xsl:choose>
|
|
148
|
-
<xsl:copy-of select="feedback/node()"/>
|
|
149
|
-
</solution>
|
|
150
|
-
</xsl:template>
|
|
151
|
-
|
|
152
|
-
<xsl:template match="*[@exercise-interactive = 'multiplechoice']" mode="runestone-to-static">
|
|
153
|
-
<!-- metadata (idx, title) -->
|
|
154
|
-
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
155
|
-
<!-- prompt, followed by ordered list of choices -->
|
|
156
|
-
<statement>
|
|
157
|
-
<xsl:copy-of select="statement/node()"/>
|
|
158
|
-
<p><ol marker="A."> <!-- conforms to RS markers -->
|
|
159
|
-
<!-- duplicate an optional @cols -->
|
|
160
|
-
<xsl:copy-of select="choices/@cols"/>
|
|
161
|
-
<xsl:for-each select="choices/choice">
|
|
162
|
-
<li>
|
|
163
|
-
<xsl:copy-of select="statement/node()"/>
|
|
164
|
-
</li>
|
|
165
|
-
</xsl:for-each>
|
|
166
|
-
</ol></p>
|
|
167
|
-
</statement>
|
|
168
|
-
<!-- Hints are authored, not derived from problem formulation -->
|
|
169
|
-
<xsl:copy-of select="hint"/>
|
|
170
|
-
<!-- Any authored answers, not derived from problem formulation. -->
|
|
171
|
-
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
172
|
-
<!-- versions on authored ones. -->
|
|
173
|
-
<xsl:copy-of select="answer"/>
|
|
174
|
-
<!-- the correct choices, as letters, in a sentence as a list -->
|
|
175
|
-
<answer>
|
|
176
|
-
<p>
|
|
177
|
-
<xsl:for-each select="choices/choice">
|
|
178
|
-
<xsl:if test="@correct = 'yes'">
|
|
179
|
-
<xsl:number format="A"/>
|
|
180
|
-
<xsl:if test="following-sibling::choice[@correct = 'yes']">
|
|
181
|
-
<xsl:text>, </xsl:text>
|
|
182
|
-
</xsl:if>
|
|
183
|
-
</xsl:if>
|
|
184
|
-
</xsl:for-each>
|
|
185
|
-
<xsl:text>.</xsl:text>
|
|
186
|
-
</p>
|
|
187
|
-
</answer>
|
|
188
|
-
<!-- Any authored solutions, not derived from problem formulation. -->
|
|
189
|
-
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
190
|
-
<!-- versions on authored ones. -->
|
|
191
|
-
<xsl:copy-of select="solution"/>
|
|
192
|
-
<!-- feedback for each choice, in a list -->
|
|
193
|
-
<solution>
|
|
194
|
-
<p><ol marker="A."> <!-- conforms to RS markers -->
|
|
195
|
-
<xsl:for-each select="choices/choice">
|
|
196
|
-
<li>
|
|
197
|
-
<title>
|
|
198
|
-
<xsl:choose>
|
|
199
|
-
<xsl:when test="@correct = 'yes'">
|
|
200
|
-
<xsl:element name="pi:localize">
|
|
201
|
-
<xsl:attribute name="string-id">correct</xsl:attribute>
|
|
202
|
-
</xsl:element>
|
|
203
|
-
</xsl:when>
|
|
204
|
-
<xsl:otherwise>
|
|
205
|
-
<xsl:element name="pi:localize">
|
|
206
|
-
<xsl:attribute name="string-id">incorrect</xsl:attribute>
|
|
207
|
-
</xsl:element>
|
|
208
|
-
</xsl:otherwise>
|
|
209
|
-
</xsl:choose>
|
|
210
|
-
</title>
|
|
211
|
-
<xsl:copy-of select="feedback/node()"/>
|
|
212
|
-
</li>
|
|
213
|
-
</xsl:for-each>
|
|
214
|
-
</ol></p>
|
|
215
|
-
</solution>
|
|
216
|
-
</xsl:template>
|
|
217
|
-
|
|
218
|
-
<xsl:template match="*[@exercise-interactive = 'parson']" mode="runestone-to-static">
|
|
219
|
-
<!-- determine these options before context switches -->
|
|
220
|
-
<xsl:variable name="language">
|
|
221
|
-
<!-- we just need the "raw" programming language, not active-language translation -->
|
|
222
|
-
<xsl:apply-templates select="." mode="get-programming-language"/>
|
|
223
|
-
</xsl:variable>
|
|
224
|
-
<xsl:variable name="b-natural" select="($language = '') or ($language = 'natural')"/>
|
|
225
|
-
<xsl:attribute name="language">
|
|
226
|
-
<xsl:value-of select="$language"/>
|
|
227
|
-
</xsl:attribute>
|
|
228
|
-
<!-- default for @indentation is "show", regards presentation -->
|
|
229
|
-
<xsl:variable name="b-indent" select="@indentation = 'hide'"/>
|
|
230
|
-
<!-- we use numbers in static versions, if requested, but ignore left/right distinction -->
|
|
231
|
-
<!-- default for @numbered is "no" -->
|
|
232
|
-
<!-- do not confuse this attribute with the @pi:numbered attribute for numbered equations -->
|
|
233
|
-
<xsl:variable name="b-numbered" select="(blocks/@numbered = 'left') or (blocks/@numbered = 'right')"/>
|
|
234
|
-
<!-- metadata (idx, title) -->
|
|
235
|
-
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
236
|
-
<!-- Statement -->
|
|
237
|
-
<statement>
|
|
238
|
-
<xsl:copy-of select="statement/node()"/>
|
|
239
|
-
<xsl:variable name="list-type">
|
|
240
|
-
<xsl:choose>
|
|
241
|
-
<xsl:when test="$b-numbered">
|
|
242
|
-
<xsl:text>ol</xsl:text>
|
|
243
|
-
</xsl:when>
|
|
244
|
-
<xsl:otherwise>
|
|
245
|
-
<xsl:text>ul</xsl:text>
|
|
246
|
-
</xsl:otherwise>
|
|
247
|
-
</xsl:choose>
|
|
248
|
-
</xsl:variable>
|
|
249
|
-
<!-- blocks, in author-defined order, via @order attribute -->
|
|
250
|
-
<p>
|
|
251
|
-
<xsl:element name="{$list-type}">
|
|
252
|
-
<xsl:if test="$list-type = 'ol'">
|
|
253
|
-
<xsl:attribute name="marker">
|
|
254
|
-
<xsl:text>1.</xsl:text>
|
|
255
|
-
</xsl:attribute>
|
|
256
|
-
</xsl:if>
|
|
257
|
-
<xsl:for-each select="blocks/block">
|
|
258
|
-
<xsl:sort select="@order"/>
|
|
259
|
-
<li>
|
|
260
|
-
<xsl:choose>
|
|
261
|
-
<xsl:when test="choice">
|
|
262
|
-
<!-- a paired distractor in the block -->
|
|
263
|
-
<!-- separate alternatives with "Either/Or" -->
|
|
264
|
-
<!-- Order is as authored -->
|
|
265
|
-
<xsl:element name="{$list-type}">
|
|
266
|
-
<xsl:attribute name="marker">
|
|
267
|
-
<xsl:choose>
|
|
268
|
-
<xsl:when test="$list-type = 'ol'">
|
|
269
|
-
<!-- sub-number as a, b, c -->
|
|
270
|
-
<xsl:text>(a)</xsl:text>
|
|
271
|
-
</xsl:when>
|
|
272
|
-
<xsl:when test="$list-type = 'ul'">
|
|
273
|
-
<!-- no markers on "bulleted" sublists -->
|
|
274
|
-
<xsl:text/>
|
|
275
|
-
</xsl:when>
|
|
276
|
-
</xsl:choose>
|
|
277
|
-
</xsl:attribute>
|
|
278
|
-
<xsl:for-each select="choice">
|
|
279
|
-
<li>
|
|
280
|
-
<xsl:if test="$list-type = 'ul'">
|
|
281
|
-
<xsl:choose>
|
|
282
|
-
<xsl:when test="not(preceding-sibling::choice)">
|
|
283
|
-
<p>
|
|
284
|
-
<xsl:element name="pi:localize">
|
|
285
|
-
<xsl:attribute name="string-id">either</xsl:attribute>
|
|
286
|
-
</xsl:element>
|
|
287
|
-
<xsl:text>:</xsl:text>
|
|
288
|
-
</p>
|
|
289
|
-
</xsl:when>
|
|
290
|
-
<xsl:otherwise>
|
|
291
|
-
<p>
|
|
292
|
-
<xsl:element name="pi:localize">
|
|
293
|
-
<xsl:attribute name="string-id">or</xsl:attribute>
|
|
294
|
-
</xsl:element>
|
|
295
|
-
<xsl:text>:</xsl:text>
|
|
296
|
-
</p>
|
|
297
|
-
</xsl:otherwise>
|
|
298
|
-
</xsl:choose>
|
|
299
|
-
</xsl:if>
|
|
300
|
-
<xsl:choose>
|
|
301
|
-
<xsl:when test="$b-natural">
|
|
302
|
-
<!-- replicate source of choice -->
|
|
303
|
-
<xsl:copy-of select="node()"/>
|
|
304
|
-
</xsl:when>
|
|
305
|
-
<xsl:otherwise>
|
|
306
|
-
<!-- computer code, make a code display -->
|
|
307
|
-
<!-- A "p" gets indentation relative to Either/Or -->
|
|
308
|
-
<!-- Otherwsie, we could make a sublist? -->
|
|
309
|
-
<p>
|
|
310
|
-
<cd>
|
|
311
|
-
<xsl:choose>
|
|
312
|
-
<xsl:when test="$b-indent">
|
|
313
|
-
<xsl:apply-templates select="." mode="strip-cline-indentation"/>
|
|
314
|
-
</xsl:when>
|
|
315
|
-
<xsl:otherwise>
|
|
316
|
-
<xsl:copy-of select="node()"/>
|
|
317
|
-
</xsl:otherwise>
|
|
318
|
-
</xsl:choose>
|
|
319
|
-
</cd>
|
|
320
|
-
</p>
|
|
321
|
-
</xsl:otherwise>
|
|
322
|
-
</xsl:choose>
|
|
323
|
-
</li>
|
|
324
|
-
</xsl:for-each>
|
|
325
|
-
</xsl:element>
|
|
326
|
-
</xsl:when>
|
|
327
|
-
<xsl:otherwise>
|
|
328
|
-
<!-- not a paired distractor -->
|
|
329
|
-
<xsl:choose>
|
|
330
|
-
<xsl:when test="$b-natural">
|
|
331
|
-
<!-- replicate source of block -->
|
|
332
|
-
<xsl:copy-of select="node()"/>
|
|
333
|
-
</xsl:when>
|
|
334
|
-
<xsl:otherwise>
|
|
335
|
-
<!-- computer code, make a code display -->
|
|
336
|
-
<cd>
|
|
337
|
-
<xsl:choose>
|
|
338
|
-
<xsl:when test="$b-indent">
|
|
339
|
-
<!-- a hard problem, reader supplies indentation -->
|
|
340
|
-
<xsl:apply-templates select="." mode="strip-cline-indentation"/>
|
|
341
|
-
</xsl:when>
|
|
342
|
-
<xsl:otherwise>
|
|
343
|
-
<!-- a little help, indentation preserved and visible -->
|
|
344
|
-
<xsl:attribute name="showspaces">
|
|
345
|
-
<xsl:text>all</xsl:text>
|
|
346
|
-
</xsl:attribute>
|
|
347
|
-
<xsl:text>
</xsl:text>
|
|
348
|
-
<xsl:copy-of select="node()"/>
|
|
349
|
-
</xsl:otherwise>
|
|
350
|
-
</xsl:choose>
|
|
351
|
-
</cd>
|
|
352
|
-
</xsl:otherwise>
|
|
353
|
-
</xsl:choose>
|
|
354
|
-
</xsl:otherwise>
|
|
355
|
-
</xsl:choose>
|
|
356
|
-
</li>
|
|
357
|
-
</xsl:for-each>
|
|
358
|
-
</xsl:element>
|
|
359
|
-
</p>
|
|
360
|
-
</statement>
|
|
361
|
-
<!-- Any authored answers, not derived from problem formulation. -->
|
|
362
|
-
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
363
|
-
<!-- versions on authored ones. -->
|
|
364
|
-
<xsl:copy-of select="answer"/>
|
|
365
|
-
<!-- Answer (potentially) -->
|
|
366
|
-
<xsl:if test="$b-numbered">
|
|
367
|
-
<!-- can make an economical answer with numbers of the -->
|
|
368
|
-
<!-- (correct) blocks in the order of the solution -->
|
|
369
|
-
<answer>
|
|
370
|
-
<p>
|
|
371
|
-
<xsl:for-each select="blocks/block">
|
|
372
|
-
<!-- default on "block" is correct="yes" -->
|
|
373
|
-
<xsl:if test="not(@correct = 'no')">
|
|
374
|
-
<xsl:value-of select="@order"/>
|
|
375
|
-
<xsl:if test="choice">
|
|
376
|
-
<xsl:for-each select="choice">
|
|
377
|
-
<!-- default on "choice" is correct="no" -->
|
|
378
|
-
<xsl:if test="@correct = 'yes'">
|
|
379
|
-
<xsl:number format="a"/>
|
|
380
|
-
</xsl:if>
|
|
381
|
-
</xsl:for-each>
|
|
382
|
-
</xsl:if>
|
|
383
|
-
<xsl:if test="following-sibling::block">
|
|
384
|
-
<xsl:text>, </xsl:text>
|
|
385
|
-
</xsl:if>
|
|
386
|
-
</xsl:if>
|
|
387
|
-
</xsl:for-each>
|
|
388
|
-
</p>
|
|
389
|
-
</answer>
|
|
390
|
-
</xsl:if>
|
|
391
|
-
<!-- Any authored solutions, not derived from problem formulation. -->
|
|
392
|
-
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
393
|
-
<!-- versions on authored ones. -->
|
|
394
|
-
<xsl:copy-of select="solution"/>
|
|
395
|
-
<!-- Solution -->
|
|
396
|
-
<solution>
|
|
397
|
-
<xsl:choose>
|
|
398
|
-
<xsl:when test="$b-natural">
|
|
399
|
-
<!-- not a programming exercise, use unordered -->
|
|
400
|
-
<!-- or description list and copy "natural" markup -->
|
|
401
|
-
<xsl:variable name="list-type">
|
|
402
|
-
<xsl:choose>
|
|
403
|
-
<xsl:when test="$b-numbered">
|
|
404
|
-
<xsl:text>dl</xsl:text>
|
|
405
|
-
</xsl:when>
|
|
406
|
-
<xsl:otherwise>
|
|
407
|
-
<xsl:text>ul</xsl:text>
|
|
408
|
-
</xsl:otherwise>
|
|
409
|
-
</xsl:choose>
|
|
410
|
-
</xsl:variable>
|
|
411
|
-
<p>
|
|
412
|
-
<xsl:element name="{$list-type}">
|
|
413
|
-
<xsl:if test="$list-type = 'dl'">
|
|
414
|
-
<xsl:attribute name="width">
|
|
415
|
-
<xsl:text>narrow</xsl:text>
|
|
416
|
-
</xsl:attribute>
|
|
417
|
-
</xsl:if>
|
|
418
|
-
<xsl:for-each select="blocks/block">
|
|
419
|
-
<!-- default on "block" is correct="yes" -->
|
|
420
|
-
<xsl:if test="not(@correct = 'no')">
|
|
421
|
-
<li>
|
|
422
|
-
<xsl:if test="$list-type = 'dl'">
|
|
423
|
-
<title>
|
|
424
|
-
<xsl:value-of select="@order"/>
|
|
425
|
-
<xsl:if test="choice">
|
|
426
|
-
<xsl:for-each select="choice">
|
|
427
|
-
<!-- default on "choice" is correct="no" -->
|
|
428
|
-
<xsl:if test="@correct = 'yes'">
|
|
429
|
-
<xsl:number format="a"/>
|
|
430
|
-
</xsl:if>
|
|
431
|
-
</xsl:for-each>
|
|
432
|
-
</xsl:if>
|
|
433
|
-
</title>
|
|
434
|
-
</xsl:if>
|
|
435
|
-
<xsl:choose>
|
|
436
|
-
<xsl:when test="choice">
|
|
437
|
-
<!-- just the correct one -->
|
|
438
|
-
<xsl:for-each select="choice">
|
|
439
|
-
<xsl:if test="@correct = 'yes'">
|
|
440
|
-
<xsl:copy-of select="node()"/>
|
|
441
|
-
</xsl:if>
|
|
442
|
-
</xsl:for-each>
|
|
443
|
-
</xsl:when>
|
|
444
|
-
<xsl:otherwise>
|
|
445
|
-
<xsl:copy-of select="node()"/>
|
|
446
|
-
</xsl:otherwise>
|
|
447
|
-
</xsl:choose>
|
|
448
|
-
</li>
|
|
449
|
-
</xsl:if>
|
|
450
|
-
</xsl:for-each>
|
|
451
|
-
</xsl:element>
|
|
452
|
-
</p>
|
|
453
|
-
</xsl:when>
|
|
454
|
-
<xsl:otherwise>
|
|
455
|
-
<!-- programming language specified, assume "cline" -->
|
|
456
|
-
<!-- structure, reconstruct as a program/input -->
|
|
457
|
-
<program>
|
|
458
|
-
<xsl:attribute name="language">
|
|
459
|
-
<xsl:value-of select="$language"/>
|
|
460
|
-
</xsl:attribute>
|
|
461
|
-
<input>
|
|
462
|
-
<xsl:for-each select="blocks/block">
|
|
463
|
-
<xsl:if test="not(@correct = 'no')">
|
|
464
|
-
<xsl:choose>
|
|
465
|
-
<xsl:when test="choice">
|
|
466
|
-
<!-- just the correct choice -->
|
|
467
|
-
<!-- default on "choice" is correct="no" -->
|
|
468
|
-
<xsl:for-each select="choice">
|
|
469
|
-
<xsl:if test="@correct = 'yes'">
|
|
470
|
-
<xsl:for-each select="cline">
|
|
471
|
-
<xsl:value-of select="."/>
|
|
472
|
-
<xsl:text>
</xsl:text>
|
|
473
|
-
</xsl:for-each>
|
|
474
|
-
</xsl:if>
|
|
475
|
-
</xsl:for-each>
|
|
476
|
-
</xsl:when>
|
|
477
|
-
<xsl:otherwise>
|
|
478
|
-
<xsl:for-each select="cline">
|
|
479
|
-
<xsl:value-of select="."/>
|
|
480
|
-
<xsl:text>
</xsl:text>
|
|
481
|
-
</xsl:for-each>
|
|
482
|
-
</xsl:otherwise>
|
|
483
|
-
</xsl:choose>
|
|
484
|
-
</xsl:if>
|
|
485
|
-
</xsl:for-each>
|
|
486
|
-
</input>
|
|
487
|
-
</program>
|
|
488
|
-
</xsl:otherwise>
|
|
489
|
-
</xsl:choose>
|
|
490
|
-
</solution>
|
|
491
|
-
</xsl:template>
|
|
492
|
-
|
|
493
|
-
<!-- If a sequence of "cline" are in a problem where a student does -->
|
|
494
|
-
<!-- not get indentation help, then we need to strip it out for -->
|
|
495
|
-
<!-- presentation in a static form. This template forms the text block, -->
|
|
496
|
-
<!-- strips leading/gross indentation with a utility template, then uses -->
|
|
497
|
-
<!-- a recursive template to wrap back into "cline". -->
|
|
498
|
-
|
|
499
|
-
<xsl:template match="block|choice" mode="strip-cline-indentation">
|
|
500
|
-
<xsl:variable name="text-block">
|
|
501
|
-
<xsl:for-each select="cline">
|
|
502
|
-
<xsl:value-of select="."/>
|
|
503
|
-
<xsl:text>
</xsl:text>
|
|
504
|
-
</xsl:for-each>
|
|
505
|
-
</xsl:variable>
|
|
506
|
-
<xsl:call-template name="restore-cline">
|
|
507
|
-
<xsl:with-param name="text">
|
|
508
|
-
<xsl:call-template name="sanitize-text">
|
|
509
|
-
<xsl:with-param name="text">
|
|
510
|
-
<xsl:value-of select="$text-block"/>
|
|
511
|
-
</xsl:with-param>
|
|
512
|
-
</xsl:call-template>
|
|
513
|
-
</xsl:with-param>
|
|
514
|
-
</xsl:call-template>
|
|
515
|
-
</xsl:template>
|
|
516
|
-
|
|
517
|
-
<xsl:template name="restore-cline">
|
|
518
|
-
<xsl:param name="text"/>
|
|
519
|
-
|
|
520
|
-
<xsl:choose>
|
|
521
|
-
<xsl:when test="$text = ''"/>
|
|
522
|
-
<xsl:otherwise>
|
|
523
|
-
<cline>
|
|
524
|
-
<xsl:value-of select="substring-before($text, '
')"/>
|
|
525
|
-
</cline>
|
|
526
|
-
<xsl:call-template name="restore-cline">
|
|
527
|
-
<xsl:with-param name="text" select="substring-after($text, '
')"/>
|
|
528
|
-
</xsl:call-template>
|
|
529
|
-
</xsl:otherwise>
|
|
530
|
-
</xsl:choose>
|
|
531
|
-
</xsl:template>
|
|
532
|
-
|
|
533
|
-
<!-- Parson (Horizontal) -->
|
|
534
|
-
|
|
535
|
-
<xsl:template match="*[@exercise-interactive = 'parson-horizontal']" mode="runestone-to-static">
|
|
536
|
-
<xsl:attribute name="language">
|
|
537
|
-
<xsl:apply-templates select="." mode="active-language"/>
|
|
538
|
-
</xsl:attribute>
|
|
539
|
-
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
540
|
-
<!-- Statement -->
|
|
541
|
-
<statement>
|
|
542
|
-
<xsl:copy-of select="statement/node()"/>
|
|
543
|
-
<!-- programming language version -->
|
|
544
|
-
<p>
|
|
545
|
-
<cd>
|
|
546
|
-
<cline>
|
|
547
|
-
<!-- hard to tell which is last once sorted, -->
|
|
548
|
-
<!-- so we just mark front *and* end -->
|
|
549
|
-
<xsl:text> | </xsl:text>
|
|
550
|
-
<xsl:for-each select="blocks/block[@order]">
|
|
551
|
-
<xsl:sort select="@order"/>
|
|
552
|
-
<xsl:apply-templates select="." mode="static-horizontal-block"/>
|
|
553
|
-
<xsl:text> | </xsl:text>
|
|
554
|
-
</xsl:for-each>
|
|
555
|
-
</cline>
|
|
556
|
-
</cd>
|
|
557
|
-
</p>
|
|
558
|
-
</statement>
|
|
559
|
-
<!-- We provide a complete solution below, -->
|
|
560
|
-
<!-- so no automatic hint or answer -->
|
|
561
|
-
<xsl:copy-of select="hint"/>
|
|
562
|
-
<xsl:copy-of select="answer"/>
|
|
563
|
-
<!-- Any authored solutions, not derived from problem formulation. -->
|
|
564
|
-
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
565
|
-
<!-- versions on authored ones. -->
|
|
566
|
-
<xsl:copy-of select="solution"/>
|
|
567
|
-
<solution>
|
|
568
|
-
<!-- programming language version -->
|
|
569
|
-
<!-- filter out distractors for the solution -->
|
|
570
|
-
<xsl:variable name="the-blocks" select="blocks/block[not(@correct = 'no')]"/>
|
|
571
|
-
<p>
|
|
572
|
-
<cd>
|
|
573
|
-
<cline>
|
|
574
|
-
<!-- authored in order, but need to follow @ref -->
|
|
575
|
-
<xsl:for-each select="$the-blocks">
|
|
576
|
-
<xsl:apply-templates select="." mode="static-horizontal-block"/>
|
|
577
|
-
<!-- context shift should handle distractors at the end -->
|
|
578
|
-
<xsl:if test="following-sibling::block">
|
|
579
|
-
<xsl:text> </xsl:text>
|
|
580
|
-
</xsl:if>
|
|
581
|
-
</xsl:for-each>
|
|
582
|
-
</cline>
|
|
583
|
-
</cd>
|
|
584
|
-
</p>
|
|
585
|
-
</solution>
|
|
586
|
-
</xsl:template>
|
|
587
|
-
|
|
588
|
-
<xsl:template match="blocks/block" mode="static-horizontal-block">
|
|
589
|
-
<xsl:choose>
|
|
590
|
-
<!-- follow @ref, copy children -->
|
|
591
|
-
<xsl:when test="@ref">
|
|
592
|
-
<xsl:copy-of select="id(@ref)/node()"/>
|
|
593
|
-
</xsl:when>
|
|
594
|
-
<!-- otherwisr duplicate children -->
|
|
595
|
-
<xsl:otherwise>
|
|
596
|
-
<xsl:copy-of select="node()"/>
|
|
597
|
-
</xsl:otherwise>
|
|
598
|
-
</xsl:choose>
|
|
599
|
-
</xsl:template>
|
|
600
|
-
|
|
601
|
-
<!-- Cardsort and Matching Problems -->
|
|
602
|
-
|
|
603
|
-
<!-- Cardsort problems are (roughly) functions, while a (general) -->
|
|
604
|
-
<!-- matching would be a relation. Both match "premise" with -->
|
|
605
|
-
<!-- "response". An implementation might have a colum of "premise" -->
|
|
606
|
-
<!-- to the left and a column of "response" to the right, with an -->
|
|
607
|
-
<!-- interface allowing the reader to make associations. -->
|
|
608
|
-
<!-- The markup for each is similar and different. Some templates -->
|
|
609
|
-
<!-- here do double-duty, some are specific (solutions). -->
|
|
610
|
-
|
|
611
|
-
<!-- Note how this template accomodates both types of problems -->
|
|
612
|
-
<!-- by using match/select and modal template names effectively. -->
|
|
613
|
-
<xsl:template match="*[@exercise-interactive = 'cardsort']|*[@exercise-interactive = 'matching']" mode="runestone-to-static">
|
|
614
|
-
<!-- metadata (idx, title) -->
|
|
615
|
-
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
616
|
-
<!-- Statement -->
|
|
617
|
-
<statement>
|
|
618
|
-
<xsl:copy-of select="statement/node()"/>
|
|
619
|
-
<xsl:apply-templates select="cardsort|matching" mode="cardsort-matching-statement"/>
|
|
620
|
-
</statement>
|
|
621
|
-
<!-- Any authored hint, answers, solutions not derived from -->
|
|
622
|
-
<!-- problem formulation. *Before* automatic solution, so -->
|
|
623
|
-
<!-- numbering matches interactive versions on authored ones. -->
|
|
624
|
-
<xsl:copy-of select="hint"/>
|
|
625
|
-
<xsl:copy-of select="answer"/>
|
|
626
|
-
<xsl:copy-of select="solution"/>
|
|
627
|
-
<!-- Automatically generated solution -->
|
|
628
|
-
<solution>
|
|
629
|
-
<xsl:apply-templates select="cardsort|matching" mode="cardsort-matching-solution"/>
|
|
630
|
-
</solution>
|
|
631
|
-
</xsl:template>
|
|
632
|
-
|
|
633
|
-
<!-- Exercise statement as a tabular -->
|
|
634
|
-
|
|
635
|
-
<!-- For a problem statement, we use a response list re-ordered -->
|
|
636
|
-
<!-- according to response/@order attribute values given by author -->
|
|
637
|
-
<xsl:template match="cardsort|matching" mode="cardsort-matching-statement">
|
|
638
|
-
|
|
639
|
-
<!-- We allow for sorting the premise and response lists, -->
|
|
640
|
-
<!-- independently of each other, so that a static version -->
|
|
641
|
-
<!-- may have a given permutation, decided by the author. -->
|
|
642
|
-
<!-- As a practical matter, a "cardsort" should have an -->
|
|
643
|
-
<!-- ordering, and premise might be easiest. A "matching" -->
|
|
644
|
-
<!-- can be authored in a desired fashion and ordering is -->
|
|
645
|
-
<!-- not needed. -->
|
|
646
|
-
|
|
647
|
-
<!-- Reorder and collect premises -->
|
|
648
|
-
<xsl:variable name="sorted-premises-rtf">
|
|
649
|
-
<xsl:for-each select="match/premise|premise">
|
|
650
|
-
<xsl:sort select="@order"/>
|
|
651
|
-
<xsl:copy-of select="."/>
|
|
652
|
-
</xsl:for-each>
|
|
653
|
-
</xsl:variable>
|
|
654
|
-
<xsl:variable name="sorted-premises" select="exsl:node-set($sorted-premises-rtf)"/>
|
|
655
|
-
|
|
656
|
-
<!-- Reorder and collect responses -->
|
|
657
|
-
<xsl:variable name="sorted-responses-rtf">
|
|
658
|
-
<xsl:for-each select="match/response|response">
|
|
659
|
-
<xsl:sort select="@order"/>
|
|
660
|
-
<xsl:copy-of select="."/>
|
|
661
|
-
</xsl:for-each>
|
|
662
|
-
</xsl:variable>
|
|
663
|
-
<xsl:variable name="sorted-responses" select="exsl:node-set($sorted-responses-rtf)"/>
|
|
664
|
-
|
|
665
|
-
<tabular>
|
|
666
|
-
<xsl:call-template name="matching-row">
|
|
667
|
-
<!-- $sorted-premises gets a root element, collecting the "premise" -->
|
|
668
|
-
<xsl:with-param name="premises" select="$sorted-premises/premise"/>
|
|
669
|
-
<!-- $sorted-responses gets a root element, collecting the "response" -->
|
|
670
|
-
<xsl:with-param name="responses" select="$sorted-responses/response"/>
|
|
671
|
-
</xsl:call-template>
|
|
672
|
-
</tabular>
|
|
673
|
-
</xsl:template>
|
|
674
|
-
|
|
675
|
-
<!-- Make one row of a tabular, recursively. We do not know which list -->
|
|
676
|
-
<!-- is longer (or they are the same length). So we "zip" them together -->
|
|
677
|
-
<!-- by making a row and then effectively discarding the contents of the -->
|
|
678
|
-
<!-- row in the recursive call. (We could pass/increment a row number -->
|
|
679
|
-
<!-- and not keep updating the node-set.) -->
|
|
680
|
-
<xsl:template name="matching-row">
|
|
681
|
-
<xsl:param name="premises"/>
|
|
682
|
-
<xsl:param name="responses"/>
|
|
683
|
-
|
|
684
|
-
<xsl:choose>
|
|
685
|
-
<xsl:when test="not($premises) and not($responses)"/>
|
|
686
|
-
<xsl:otherwise>
|
|
687
|
-
<row>
|
|
688
|
-
<cell>
|
|
689
|
-
<xsl:if test="count($premises) > 1">
|
|
690
|
-
<xsl:attribute name="bottom">
|
|
691
|
-
<xsl:text>minor</xsl:text>
|
|
692
|
-
</xsl:attribute>
|
|
693
|
-
</xsl:if>
|
|
694
|
-
<xsl:copy-of select="$premises[1]/node()"/>
|
|
695
|
-
</cell>
|
|
696
|
-
<!-- An empty (two-character wide) column is a bit of a hack to get -->
|
|
697
|
-
<!-- a visual separation. Could we do better with paragraph cells? -->
|
|
698
|
-
<cell bottom="none"><nbsp/><nbsp/></cell>
|
|
699
|
-
<cell>
|
|
700
|
-
<xsl:if test="count($responses) > 1">
|
|
701
|
-
<xsl:attribute name="bottom">
|
|
702
|
-
<xsl:text>minor</xsl:text>
|
|
703
|
-
</xsl:attribute>
|
|
704
|
-
</xsl:if>
|
|
705
|
-
<xsl:copy-of select="$responses[1]/node()"/>
|
|
706
|
-
</cell>
|
|
707
|
-
</row>
|
|
708
|
-
<xsl:call-template name="matching-row">
|
|
709
|
-
<xsl:with-param name="premises" select="$premises[position() > 1]"/>
|
|
710
|
-
<xsl:with-param name="responses" select="$responses[position() > 1]"/>
|
|
711
|
-
</xsl:call-template>
|
|
712
|
-
</xsl:otherwise>
|
|
713
|
-
</xsl:choose>
|
|
714
|
-
</xsl:template>
|
|
715
|
-
|
|
716
|
-
<!-- Solutions are lists of lists, but seem to -->
|
|
717
|
-
<!-- require two different, but similar, templates. -->
|
|
718
|
-
|
|
719
|
-
<!-- For a solution, we make an unordered list of the responses -->
|
|
720
|
-
<!-- (the "buckets" in true cardsort terminology) and for each -->
|
|
721
|
-
<!-- we make a sub-list wioth the premises that match (the "cards" -->
|
|
722
|
-
<!-- in true cardsort terminology. Note that potential distractors -->
|
|
723
|
-
<!-- are a premise with no response (empty sub-list) and a response -->
|
|
724
|
-
<!-- with no premise (a premise that is null-ish). -->
|
|
725
|
-
<xsl:template match="cardsort" mode="cardsort-matching-solution">
|
|
726
|
-
<p><ul>
|
|
727
|
-
<xsl:for-each select="match">
|
|
728
|
-
<li>
|
|
729
|
-
<p>
|
|
730
|
-
<xsl:choose>
|
|
731
|
-
<xsl:when test="response">
|
|
732
|
-
<xsl:copy-of select="response"/>
|
|
733
|
-
</xsl:when>
|
|
734
|
-
<xsl:otherwise>
|
|
735
|
-
<xsl:text>(</xsl:text>
|
|
736
|
-
<xsl:element name="pi:localize">
|
|
737
|
-
<xsl:attribute name="string-id">uncategorized</xsl:attribute>
|
|
738
|
-
</xsl:element>
|
|
739
|
-
<xsl:text>)</xsl:text>
|
|
740
|
-
</xsl:otherwise>
|
|
741
|
-
</xsl:choose>
|
|
742
|
-
<xsl:if test="premise">
|
|
743
|
-
<ul>
|
|
744
|
-
<xsl:for-each select="premise">
|
|
745
|
-
<li>
|
|
746
|
-
<xsl:copy-of select="."/>
|
|
747
|
-
</li>
|
|
748
|
-
</xsl:for-each>
|
|
749
|
-
</ul>
|
|
750
|
-
</xsl:if>
|
|
751
|
-
</p>
|
|
752
|
-
</li>
|
|
753
|
-
</xsl:for-each>
|
|
754
|
-
</ul></p>
|
|
755
|
-
</xsl:template>
|
|
756
|
-
|
|
757
|
-
<!-- For a solution, we make an unordered list of the -->
|
|
758
|
-
<!-- responses (mirroring the cardsort organization) and -->
|
|
759
|
-
<!-- for each we make a sub-list with the premises that. -->
|
|
760
|
-
<!-- are matched. Distractors are a premise with no -->
|
|
761
|
-
<!-- response (empty sub-list) and a response with no -->
|
|
762
|
-
<!-- premise (a premise that is null-ish). S-->
|
|
763
|
-
<xsl:template match="matching" mode="cardsort-matching-solution">
|
|
764
|
-
<p><ul>
|
|
765
|
-
<xsl:for-each select="response">
|
|
766
|
-
<xsl:variable name="response-xmlid-fenced" select="concat('|', @xml:id, '|')"/>
|
|
767
|
-
<li>
|
|
768
|
-
<p>
|
|
769
|
-
<xsl:copy-of select="."/>
|
|
770
|
-
<!-- form list items of matching premise -->
|
|
771
|
-
<!-- this could be empty, so we not open -->
|
|
772
|
-
<!-- a sub-list prematurely -->
|
|
773
|
-
<xsl:variable name="matched-premises-rtf">
|
|
774
|
-
<!-- context is a "response" step up to get "permise" -->
|
|
775
|
-
<xsl:for-each select="parent::matching/premise">
|
|
776
|
-
<xsl:variable name="the-ref-fenced" select="concat('|', translate(@ref, ' ', '|'), '|')"/>
|
|
777
|
-
<!-- the test for adjacency -->
|
|
778
|
-
<xsl:if test="contains($the-ref-fenced, $response-xmlid-fenced)">
|
|
779
|
-
<li>
|
|
780
|
-
<xsl:copy-of select="."/>
|
|
781
|
-
</li>
|
|
782
|
-
</xsl:if>
|
|
783
|
-
</xsl:for-each>
|
|
784
|
-
</xsl:variable>
|
|
785
|
-
<xsl:variable name="matched-premises" select="exsl:node-set($matched-premises-rtf)"/>
|
|
786
|
-
<!-- create a non-empty sublist of matched premise -->
|
|
787
|
-
<xsl:if test="$matched-premises/li">
|
|
788
|
-
<ul>
|
|
789
|
-
<xsl:copy-of select="$matched-premises"/>
|
|
790
|
-
</ul>
|
|
791
|
-
</xsl:if>
|
|
792
|
-
</p>
|
|
793
|
-
</li>
|
|
794
|
-
</xsl:for-each>
|
|
795
|
-
<!-- And we need to catch premises that do not get -->
|
|
796
|
-
<!-- matched to any response (through null-ish @ref) -->
|
|
797
|
-
<!-- NB: context is now the "matching" -->
|
|
798
|
-
<xsl:variable name="unmatched-premises-rtf">
|
|
799
|
-
<xsl:for-each select="premise">
|
|
800
|
-
<xsl:if test="not(@ref) or (normalize-space(@ref) = '')">
|
|
801
|
-
<li>
|
|
802
|
-
<xsl:copy-of select="."/>
|
|
803
|
-
</li>
|
|
804
|
-
</xsl:if>
|
|
805
|
-
</xsl:for-each>
|
|
806
|
-
</xsl:variable>
|
|
807
|
-
<xsl:variable name="unmatched-premises" select="exsl:node-set($unmatched-premises-rtf)"/>
|
|
808
|
-
<!-- Make a top-level list item "uncategorized" response,-->
|
|
809
|
-
<!-- and populate it with a sub-list of all the premise -->
|
|
810
|
-
<!-- that do not get matched with anything -->
|
|
811
|
-
<xsl:if test="$unmatched-premises/li">
|
|
812
|
-
<li><p>
|
|
813
|
-
<xsl:text>(</xsl:text>
|
|
814
|
-
<xsl:element name="pi:localize">
|
|
815
|
-
<xsl:attribute name="string-id">uncategorized</xsl:attribute>
|
|
816
|
-
</xsl:element>
|
|
817
|
-
<xsl:text>)</xsl:text>
|
|
818
|
-
<ul>
|
|
819
|
-
<xsl:copy-of select="$unmatched-premises/li"/>
|
|
820
|
-
</ul>
|
|
821
|
-
</p></li>
|
|
822
|
-
</xsl:if>
|
|
823
|
-
</ul></p>
|
|
824
|
-
</xsl:template>
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
<!-- Clickable Area -->
|
|
828
|
-
|
|
829
|
-
<xsl:template match="*[@exercise-interactive = 'clickablearea']" mode="runestone-to-static">
|
|
830
|
-
<!-- metadata (idx, title) -->
|
|
831
|
-
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
832
|
-
<!-- Statement -->
|
|
833
|
-
<statement>
|
|
834
|
-
<xsl:copy-of select="statement/node()"/>
|
|
835
|
-
<xsl:apply-templates select="areas" mode="static-areas"/>
|
|
836
|
-
</statement>
|
|
837
|
-
<xsl:copy-of select="hint"/>
|
|
838
|
-
<!-- Any authored answers, not derived from problem formulation. -->
|
|
839
|
-
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
840
|
-
<!-- versions on authored ones. -->
|
|
841
|
-
<xsl:copy-of select="answer"/>
|
|
842
|
-
<answer>
|
|
843
|
-
<p>
|
|
844
|
-
<xsl:element name="pi:localize">
|
|
845
|
-
<xsl:attribute name="string-id">correct</xsl:attribute>
|
|
846
|
-
</xsl:element>
|
|
847
|
-
<xsl:text>: </xsl:text>
|
|
848
|
-
<xsl:for-each select="areas//area[not(@correct = 'no')]">
|
|
849
|
-
<xsl:apply-templates select="." mode="answer-areas"/>
|
|
850
|
-
<xsl:if test="not(position() = last())">
|
|
851
|
-
<xsl:text>; </xsl:text>
|
|
852
|
-
</xsl:if>
|
|
853
|
-
</xsl:for-each>
|
|
854
|
-
<xsl:text>.</xsl:text>
|
|
855
|
-
<xsl:text> </xsl:text>
|
|
856
|
-
<xsl:element name="pi:localize">
|
|
857
|
-
<xsl:attribute name="string-id">incorrect</xsl:attribute>
|
|
858
|
-
</xsl:element>
|
|
859
|
-
<xsl:text>: </xsl:text>
|
|
860
|
-
<xsl:for-each select="areas//area[@correct = 'no']">
|
|
861
|
-
<xsl:apply-templates select="." mode="answer-areas"/>
|
|
862
|
-
<xsl:if test="not(position() = last())">
|
|
863
|
-
<xsl:text>; </xsl:text>
|
|
864
|
-
</xsl:if>
|
|
865
|
-
</xsl:for-each>
|
|
866
|
-
<xsl:text>.</xsl:text>
|
|
867
|
-
</p>
|
|
868
|
-
<xsl:copy-of select="feedback/node()"/>
|
|
869
|
-
</answer>
|
|
870
|
-
<!-- Any authored solutions, not derived from problem formulation. -->
|
|
871
|
-
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
872
|
-
<!-- versions on authored ones. -->
|
|
873
|
-
<xsl:copy-of select="solution"/>
|
|
874
|
-
<!-- A text version can get markup of correct and incorrect areas -->
|
|
875
|
-
<!-- (italics, strikethrough) but no good way to markup code easily. -->
|
|
876
|
-
<!-- So no "solution" for code versions. -->
|
|
877
|
-
<xsl:if test="not(areas/cline)">
|
|
878
|
-
<solution>
|
|
879
|
-
<xsl:apply-templates select="areas/node()" mode="solution-areas"/>
|
|
880
|
-
</solution>
|
|
881
|
-
</xsl:if>
|
|
882
|
-
</xsl:template>
|
|
883
|
-
|
|
884
|
-
<!-- We do a xerox'ing pass to construct the problem. -->
|
|
885
|
-
<!-- (1) "area" gets dropped (invisible in static) -->
|
|
886
|
-
<!-- [could italicize correct and incorrect?] -->
|
|
887
|
-
<!-- (2) "cline" get reconstructed as a "program" -->
|
|
888
|
-
|
|
889
|
-
<xsl:template match="node()|@*" mode="static-areas">
|
|
890
|
-
<xsl:copy>
|
|
891
|
-
<xsl:apply-templates select="node()|@*" mode="static-areas"/>
|
|
892
|
-
</xsl:copy>
|
|
893
|
-
</xsl:template>
|
|
894
|
-
|
|
895
|
-
<xsl:template match="areas" mode="static-areas">
|
|
896
|
-
<xsl:choose>
|
|
897
|
-
<xsl:when test="cline">
|
|
898
|
-
<!-- code, so make a "program" structure -->
|
|
899
|
-
<program>
|
|
900
|
-
<xsl:attribute name="language">
|
|
901
|
-
<xsl:apply-templates select="." mode="get-programming-language"/>
|
|
902
|
-
</xsl:attribute>
|
|
903
|
-
<input>
|
|
904
|
-
<xsl:apply-templates select="cline" mode="static-areas"/>
|
|
905
|
-
</input>
|
|
906
|
-
</program>
|
|
907
|
-
</xsl:when>
|
|
908
|
-
<xsl:otherwise>
|
|
909
|
-
<!-- regular text, this will match a default template later -->
|
|
910
|
-
<xsl:apply-templates select="*" mode="static-areas"/>
|
|
911
|
-
</xsl:otherwise>
|
|
912
|
-
</xsl:choose>
|
|
913
|
-
</xsl:template>
|
|
914
|
-
|
|
915
|
-
<xsl:template match="areas/cline" mode="static-areas">
|
|
916
|
-
<xsl:apply-templates select="text()|area" mode="static-areas"/>
|
|
917
|
-
<xsl:text>
</xsl:text>
|
|
918
|
-
</xsl:template>
|
|
919
|
-
|
|
920
|
-
<xsl:template match="cline/text()" mode="static-areas">
|
|
921
|
-
<xsl:value-of select="."/>
|
|
922
|
-
</xsl:template>
|
|
923
|
-
|
|
924
|
-
<!-- NB: don't apply to attributes of an "area" (just @correct) -->
|
|
925
|
-
<xsl:template match="area" mode="static-areas">
|
|
926
|
-
<xsl:apply-templates select="node()" mode="static-areas"/>
|
|
927
|
-
</xsl:template>
|
|
928
|
-
|
|
929
|
-
<!-- Modal templates reproduce answers, which could have some -->
|
|
930
|
-
<!-- markup in them? We enter here at each "area" to form the -->
|
|
931
|
-
<!-- lists of correct and incorrect areas. -->
|
|
932
|
-
|
|
933
|
-
<xsl:template match="node()|@*" mode="answer-areas">
|
|
934
|
-
<xsl:copy>
|
|
935
|
-
<xsl:apply-templates select="node()|@*" mode="answer-areas"/>
|
|
936
|
-
</xsl:copy>
|
|
937
|
-
</xsl:template>
|
|
938
|
-
|
|
939
|
-
<xsl:template match="area[parent::cline]" mode="answer-areas">
|
|
940
|
-
<c>
|
|
941
|
-
<!-- NB: don't xerox attributes of an "area" (just @correct) -->
|
|
942
|
-
<xsl:apply-templates select="node()" mode="answer-areas"/>
|
|
943
|
-
</c>
|
|
944
|
-
</xsl:template>
|
|
945
|
-
|
|
946
|
-
<xsl:template match="area[not(parent::cline) and not(@correct = 'no')]" mode="answer-areas">
|
|
947
|
-
<em>
|
|
948
|
-
<!-- NB: don't xerox attributes of an "area" (just @correct) -->
|
|
949
|
-
<xsl:apply-templates select="node()" mode="answer-areas"/>
|
|
950
|
-
</em>
|
|
951
|
-
</xsl:template>
|
|
952
|
-
|
|
953
|
-
<xsl:template match="area[not(parent::cline) and (@correct = 'no')]" mode="answer-areas">
|
|
954
|
-
<delete>
|
|
955
|
-
<!-- NB: don't xerox attributes of an "area" (just @correct) -->
|
|
956
|
-
<xsl:apply-templates select="node()" mode="answer-areas"/>
|
|
957
|
-
</delete>
|
|
958
|
-
</xsl:template>
|
|
959
|
-
|
|
960
|
-
<!-- protect from low-level routines in -common -->
|
|
961
|
-
<xsl:template match="cline/area/text()" mode="answer-areas">
|
|
962
|
-
<xsl:value-of select="."/>
|
|
963
|
-
</xsl:template>
|
|
964
|
-
|
|
965
|
-
<!-- For a text version (only, not a code version) we xerox -->
|
|
966
|
-
<!-- the contents of "areas" and slide-in some highlighting -->
|
|
967
|
-
<!-- of the correct and incorrect "area". -->
|
|
968
|
-
|
|
969
|
-
<xsl:template match="node()|@*" mode="solution-areas">
|
|
970
|
-
<xsl:copy>
|
|
971
|
-
<xsl:apply-templates select="node()|@*" mode="solution-areas"/>
|
|
972
|
-
</xsl:copy>
|
|
973
|
-
</xsl:template>
|
|
974
|
-
|
|
975
|
-
<xsl:template match="area[not(@correct = 'no')]" mode="solution-areas">
|
|
976
|
-
<em>
|
|
977
|
-
<!-- NB: don't xerox attributes of an "area" (just @correct) -->
|
|
978
|
-
<xsl:apply-templates select="node()" mode="solution-areas"/>
|
|
979
|
-
</em>
|
|
980
|
-
</xsl:template>
|
|
981
|
-
|
|
982
|
-
<xsl:template match="area[@correct = 'no']" mode="solution-areas">
|
|
983
|
-
<delete>
|
|
984
|
-
<!-- NB: don't xerox attributes of an "area" (just @correct) -->
|
|
985
|
-
<xsl:apply-templates select="node()" mode="solution-areas"/>
|
|
986
|
-
</delete>
|
|
987
|
-
</xsl:template>
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
<!-- Select -->
|
|
991
|
-
|
|
992
|
-
<xsl:template match="*[@exercise-interactive = 'select']" mode="runestone-to-static">
|
|
993
|
-
<!-- metadata (idx, title) -->
|
|
994
|
-
<xsl:copy-of select="select/preceding-sibling::*"/>
|
|
995
|
-
|
|
996
|
-
<!-- identify the type of "select" -->
|
|
997
|
-
<!-- duplicated in "pretext-runestone.xsl" -->
|
|
998
|
-
<!-- No good place to put this, since static versions -->
|
|
999
|
-
<!-- are forned in assembly phase and we do not want -->
|
|
1000
|
-
<!-- to introduce too many templates there. -->
|
|
1001
|
-
<!-- Save off which type, since context is lost looping over refs -->
|
|
1002
|
-
<xsl:variable name="select-variant">
|
|
1003
|
-
<xsl:choose>
|
|
1004
|
-
<!-- Runestone JS picks a random problem from many-->
|
|
1005
|
-
<xsl:when test="select/@grade='random'">
|
|
1006
|
-
<xsl:text>random</xsl:text>
|
|
1007
|
-
</xsl:when>
|
|
1008
|
-
<!-- Two questions, split across roster into A, B groups. -->
|
|
1009
|
-
<xsl:when test="select/@grade='ab-experiment'">
|
|
1010
|
-
<xsl:text>ab-experiment</xsl:text>
|
|
1011
|
-
</xsl:when>
|
|
1012
|
-
<!-- Two questions (usually), the first will always be graded, -->
|
|
1013
|
-
<!-- while any others may be worked and may be helpful. -->
|
|
1014
|
-
<!-- Colloquially known as a "toggle lock" question. -->
|
|
1015
|
-
<xsl:when test="select/@grade='first'">
|
|
1016
|
-
<xsl:text>first</xsl:text>
|
|
1017
|
-
</xsl:when>
|
|
1018
|
-
<!-- Two questions (usually), any one may be -->
|
|
1019
|
-
<!-- chosen by the reader to be graded. -->
|
|
1020
|
-
<!-- Colloquially known as a "toggle " question. -->
|
|
1021
|
-
<xsl:when test="select/@grade='any'">
|
|
1022
|
-
<xsl:text>any</xsl:text>
|
|
1023
|
-
</xsl:when>
|
|
1024
|
-
<!-- default to "random" selection -->
|
|
1025
|
-
<xsl:otherwise>
|
|
1026
|
-
<xsl:text>random</xsl:text>
|
|
1027
|
-
</xsl:otherwise>
|
|
1028
|
-
</xsl:choose>
|
|
1029
|
-
</xsl:variable>
|
|
1030
|
-
<!-- One simple sentence in a "p", typically presented -->
|
|
1031
|
-
<!-- just after a lead-in title from "exercise" -->
|
|
1032
|
-
<p>
|
|
1033
|
-
<!-- some lead-in explanation -->
|
|
1034
|
-
<xsl:text>Runestone-only: </xsl:text>
|
|
1035
|
-
<xsl:choose>
|
|
1036
|
-
<xsl:when test="$select-variant = 'random'">
|
|
1037
|
-
<xsl:text>exercise to grade will be automatically chosen by Runestone from </xsl:text>
|
|
1038
|
-
</xsl:when>
|
|
1039
|
-
<xsl:when test="$select-variant = 'ab-experiment'">
|
|
1040
|
-
<xsl:text>an A/B experiment (named </xsl:text>
|
|
1041
|
-
<c>
|
|
1042
|
-
<xsl:value-of select="select/@experiment-name"/>
|
|
1043
|
-
</c>
|
|
1044
|
-
<xsl:text>) with </xsl:text>
|
|
1045
|
-
</xsl:when>
|
|
1046
|
-
<xsl:when test="$select-variant = 'first'">
|
|
1047
|
-
<xsl:text>a toggle question where the question graded is </xsl:text>
|
|
1048
|
-
<em>always</em>
|
|
1049
|
-
<xsl:text> the first of </xsl:text>
|
|
1050
|
-
</xsl:when>
|
|
1051
|
-
<xsl:when test="$select-variant = 'any'">
|
|
1052
|
-
<xsl:text>a toggle question where the question graded is </xsl:text>
|
|
1053
|
-
<em>any</em>
|
|
1054
|
-
<xsl:text> question chosen by the reader from </xsl:text>
|
|
1055
|
-
</xsl:when>
|
|
1056
|
-
</xsl:choose>
|
|
1057
|
-
<!-- list "xref" to questions -->
|
|
1058
|
-
<xsl:for-each select="str:tokenize(select/@questions, ' ,')">
|
|
1059
|
-
<!-- cross-reference, will be in default document style -->
|
|
1060
|
-
<xref>
|
|
1061
|
-
<xsl:attribute name="ref">
|
|
1062
|
-
<xsl:value-of select="."/>
|
|
1063
|
-
</xsl:attribute>
|
|
1064
|
-
</xref>
|
|
1065
|
-
<!-- punctuation -->
|
|
1066
|
-
<xsl:choose>
|
|
1067
|
-
<xsl:when test="not($select-variant = 'ab-experiment')">
|
|
1068
|
-
<xsl:choose>
|
|
1069
|
-
<!-- penultimate; trailing comma, plus "or" -->
|
|
1070
|
-
<xsl:when test="count(following-sibling::token) = 1">
|
|
1071
|
-
<xsl:text>, or </xsl:text>
|
|
1072
|
-
</xsl:when>
|
|
1073
|
-
<!-- more, more coming; trailing comma -->
|
|
1074
|
-
<xsl:when test="following-sibling::token">
|
|
1075
|
-
<xsl:text>, </xsl:text>
|
|
1076
|
-
</xsl:when>
|
|
1077
|
-
<!-- done; need final period -->
|
|
1078
|
-
<xsl:otherwise>
|
|
1079
|
-
<xsl:text>.</xsl:text>
|
|
1080
|
-
</xsl:otherwise>
|
|
1081
|
-
</xsl:choose>
|
|
1082
|
-
</xsl:when>
|
|
1083
|
-
<xsl:otherwise>
|
|
1084
|
-
<xsl:choose>
|
|
1085
|
-
<!-- finish "A", and separate from "B" -->
|
|
1086
|
-
<xsl:when test="following-sibling::token">
|
|
1087
|
-
<xsl:text> as (A)</xsl:text>
|
|
1088
|
-
<xsl:text> and </xsl:text>
|
|
1089
|
-
</xsl:when>
|
|
1090
|
-
<!-- final period -->
|
|
1091
|
-
<xsl:otherwise>
|
|
1092
|
-
<xsl:text> as (B).</xsl:text>
|
|
1093
|
-
</xsl:otherwise>
|
|
1094
|
-
</xsl:choose>
|
|
1095
|
-
</xsl:otherwise>
|
|
1096
|
-
</xsl:choose>
|
|
1097
|
-
</xsl:for-each>
|
|
1098
|
-
</p>
|
|
1099
|
-
</xsl:template>
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
<!-- Fill-In the Blanks (Basic) -->
|
|
1103
|
-
|
|
1104
|
-
<xsl:template match="*[@exercise-interactive = 'fillin-basic']" mode="runestone-to-static">
|
|
1105
|
-
<!-- metadata (idx, title) -->
|
|
1106
|
-
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
1107
|
-
<!-- reproduce statement identically, but replace var w/ fillin -->
|
|
1108
|
-
<xsl:apply-templates select="statement" mode="fillin-statement"/>
|
|
1109
|
-
<!-- Any authored hints, answers, solutions, not derived from -->
|
|
1110
|
-
<!-- problem formulation. *Before* automatic ones, so numbering -->
|
|
1111
|
-
<!-- matches interactive versions on authored ones. -->
|
|
1112
|
-
<xsl:copy-of select="hint"/>
|
|
1113
|
-
<xsl:copy-of select="answer"/>
|
|
1114
|
-
<xsl:copy-of select="solution"/>
|
|
1115
|
-
<xsl:apply-templates select="statement" mode="fillin-solution"/>
|
|
1116
|
-
</xsl:template>
|
|
1117
|
-
|
|
1118
|
-
<!-- Fillin Statement -->
|
|
1119
|
-
<xsl:template match="node()|@*" mode="fillin-statement">
|
|
1120
|
-
<xsl:copy>
|
|
1121
|
-
<xsl:apply-templates select="node()|@*" mode="fillin-statement"/>
|
|
1122
|
-
</xsl:copy>
|
|
1123
|
-
</xsl:template>
|
|
1124
|
-
|
|
1125
|
-
<xsl:template match="var" mode="fillin-statement">
|
|
1126
|
-
<fillin>
|
|
1127
|
-
<xsl:attribute name="characters">
|
|
1128
|
-
<xsl:choose>
|
|
1129
|
-
<xsl:when test="@width">
|
|
1130
|
-
<xsl:value-of select="@width"/>
|
|
1131
|
-
</xsl:when>
|
|
1132
|
-
<xsl:otherwise>
|
|
1133
|
-
<!-- arbitrary default width -->
|
|
1134
|
-
<xsl:text>5</xsl:text>
|
|
1135
|
-
</xsl:otherwise>
|
|
1136
|
-
</xsl:choose>
|
|
1137
|
-
</xsl:attribute>
|
|
1138
|
-
</fillin>
|
|
1139
|
-
</xsl:template>
|
|
1140
|
-
|
|
1141
|
-
<!-- Fillin complete solution -->
|
|
1142
|
-
|
|
1143
|
-
<xsl:template match="node()|@*" mode="fillin-solution">
|
|
1144
|
-
<xsl:copy>
|
|
1145
|
-
<xsl:apply-templates select="node()|@*" mode="fillin-solution"/>
|
|
1146
|
-
</xsl:copy>
|
|
1147
|
-
</xsl:template>
|
|
1148
|
-
|
|
1149
|
-
<!-- Don't duplicate xml:id. Nobody should point into the solution. -->
|
|
1150
|
-
<!-- Note that any internal link references will point to the original not the copy -->
|
|
1151
|
-
<xsl:template match="@xml:id" mode="fillin-solution"/>
|
|
1152
|
-
|
|
1153
|
-
<!-- Append to a label -->
|
|
1154
|
-
<xsl:template match="@label" mode="fillin-solution">
|
|
1155
|
-
<xsl:attribute name="label">
|
|
1156
|
-
<xsl:value-of select="."/>
|
|
1157
|
-
<xsl:text>-fitb-solution</xsl:text>
|
|
1158
|
-
</xsl:attribute>
|
|
1159
|
-
</xsl:template>
|
|
1160
|
-
|
|
1161
|
-
<xsl:template match="statement" mode="fillin-solution">
|
|
1162
|
-
<xsl:variable name="exercise" select=".."/>
|
|
1163
|
-
<solution>
|
|
1164
|
-
<xsl:apply-templates select="node()|@*" mode="fillin-solution"/>
|
|
1165
|
-
<!-- xerox feedback for correct response on each var -->
|
|
1166
|
-
<xsl:for-each select="../setup/var/condition[1]/feedback">
|
|
1167
|
-
<xsl:apply-templates select="node()" mode="fillin-solution"/>
|
|
1168
|
-
</xsl:for-each>
|
|
1169
|
-
<xsl:for-each select=".//fillin[@answer]">
|
|
1170
|
-
<xsl:variable name="fillin-name" select="@name"/>
|
|
1171
|
-
<xsl:variable name="fillin-pos" select="position()"/>
|
|
1172
|
-
<xsl:choose>
|
|
1173
|
-
<!-- If #evaluate matches by name, find feedback on a correct result -->
|
|
1174
|
-
<xsl:when test="$exercise/evaluation/evaluate[@name='$fillin-name']/test[@correct='yes']">
|
|
1175
|
-
<xsl:apply-templates select="$exercise/evaluation/evaluate[@name='$fillin-name']/test[@correct='yes']/feedback/node()" mode="fillin-solution"/>
|
|
1176
|
-
</xsl:when>
|
|
1177
|
-
<!-- Otherwise #evaluate matches by order, find feedback on a correct result -->
|
|
1178
|
-
<xsl:when test="$exercise/evaluation/evaluate[$fillin-pos]/test[@correct='yes']">
|
|
1179
|
-
<xsl:apply-templates select="$exercise/evaluation/evaluate[$fillin-pos]/test[@correct='yes']/feedback/node()" mode="fillin-solution"/>
|
|
1180
|
-
</xsl:when>
|
|
1181
|
-
</xsl:choose>
|
|
1182
|
-
</xsl:for-each>
|
|
1183
|
-
<xsl:if test="../evaluation[@answers-coupled='yes']">
|
|
1184
|
-
<xsl:apply-templates select="$exercise/evaluation/evaluate[@all='yes']/test[@correct='yes']/feedback/node()" mode="fillin-solution"/>
|
|
1185
|
-
</xsl:if>
|
|
1186
|
-
</solution>
|
|
1187
|
-
</xsl:template>
|
|
1188
|
-
|
|
1189
|
-
<xsl:template match="var" mode="fillin-solution">
|
|
1190
|
-
<!-- NB: this code is used in formulating HTML representations -->
|
|
1191
|
-
<!-- count location of (context) "var" in problem statement -->
|
|
1192
|
-
<xsl:variable name="location">
|
|
1193
|
-
<xsl:number from="statement"/>
|
|
1194
|
-
</xsl:variable>
|
|
1195
|
-
<!-- locate corresponding "var" in "setup" -->
|
|
1196
|
-
<xsl:variable name="setup-var" select="ancestor::exercise/setup/var[position() = $location]"/>
|
|
1197
|
-
|
|
1198
|
-
<!-- Know can tell what the correct answer is, from first "condition"-->
|
|
1199
|
-
<fillin characters="1"/>
|
|
1200
|
-
<xsl:choose>
|
|
1201
|
-
<xsl:when test="$setup-var/condition[1]/@number">
|
|
1202
|
-
<m>
|
|
1203
|
-
<xsl:value-of select="$setup-var/condition[1]/@number"/>
|
|
1204
|
-
</m>
|
|
1205
|
-
</xsl:when>
|
|
1206
|
-
<xsl:when test="$setup-var/condition[1]/@string">
|
|
1207
|
-
<xsl:value-of select="$setup-var/condition[1]/@string"/>
|
|
1208
|
-
</xsl:when>
|
|
1209
|
-
</xsl:choose>
|
|
1210
|
-
<fillin characters="1"/>
|
|
1211
|
-
</xsl:template>
|
|
1212
|
-
|
|
1213
|
-
<!-- Fill-In the Blanks (Complete) -->
|
|
1214
|
-
|
|
1215
|
-
<xsl:template match="*[@exercise-interactive = 'fillin']" mode="runestone-to-static">
|
|
1216
|
-
<!-- metadata (idx, title) -->
|
|
1217
|
-
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
1218
|
-
<!-- reproduce statement identically, but replace var w/ fillin -->
|
|
1219
|
-
<xsl:apply-templates select="statement" mode="fillin-statement"/>
|
|
1220
|
-
<!-- Any authored hints, answers, solutions, not derived from -->
|
|
1221
|
-
<!-- problem formulation. *Before* automatic ones, so numbering -->
|
|
1222
|
-
<!-- matches interactive versions on authored ones. -->
|
|
1223
|
-
<xsl:copy-of select="hint"/>
|
|
1224
|
-
<xsl:copy-of select="answer"/>
|
|
1225
|
-
<xsl:choose>
|
|
1226
|
-
<xsl:when test="solution[@include-automatic='no']">
|
|
1227
|
-
<xsl:copy-of select="solution"/>
|
|
1228
|
-
</xsl:when>
|
|
1229
|
-
<xsl:otherwise>
|
|
1230
|
-
<xsl:apply-templates select="statement" mode="fillin-solution"/>
|
|
1231
|
-
<xsl:copy-of select="solution"/>
|
|
1232
|
-
</xsl:otherwise>
|
|
1233
|
-
</xsl:choose>
|
|
1234
|
-
</xsl:template>
|
|
1235
|
-
|
|
1236
|
-
<!-- Fillin Statement -->
|
|
1237
|
-
<xsl:template match="fillin" mode="fillin-statement">
|
|
1238
|
-
<fillin>
|
|
1239
|
-
<xsl:attribute name="characters">
|
|
1240
|
-
<xsl:choose>
|
|
1241
|
-
<xsl:when test="@width">
|
|
1242
|
-
<xsl:value-of select="@width"/>
|
|
1243
|
-
</xsl:when>
|
|
1244
|
-
<xsl:otherwise>
|
|
1245
|
-
<!-- arbitrary default width -->
|
|
1246
|
-
<xsl:text>5</xsl:text>
|
|
1247
|
-
</xsl:otherwise>
|
|
1248
|
-
</xsl:choose>
|
|
1249
|
-
</xsl:attribute>
|
|
1250
|
-
</fillin>
|
|
1251
|
-
</xsl:template>
|
|
1252
|
-
|
|
1253
|
-
<!-- Fillin complete solution -->
|
|
1254
|
-
<xsl:template match="fillin" mode="fillin-solution">
|
|
1255
|
-
<!-- Correct answer is in @answer. -->
|
|
1256
|
-
<fillin characters="1"/>
|
|
1257
|
-
<xsl:choose>
|
|
1258
|
-
<xsl:when test="@mode='math' or @mode='number'">
|
|
1259
|
-
<m><xsl:value-of select="@answer"/></m>
|
|
1260
|
-
</xsl:when>
|
|
1261
|
-
<xsl:otherwise>
|
|
1262
|
-
<xsl:value-of select="@answer"/>
|
|
1263
|
-
</xsl:otherwise>
|
|
1264
|
-
</xsl:choose>
|
|
1265
|
-
<fillin characters="1"/>
|
|
1266
|
-
</xsl:template>
|
|
1267
|
-
|
|
1268
|
-
<!-- Short Answer -->
|
|
1269
|
-
|
|
1270
|
-
<!-- Authored with a "response" element, we effectively drop it here -->
|
|
1271
|
-
<xsl:template match="*[@exercise-interactive = 'shortanswer']" mode="runestone-to-static">
|
|
1272
|
-
<!-- metadata (idx, title) -->
|
|
1273
|
-
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
1274
|
-
<!-- reproduce usual components -->
|
|
1275
|
-
<xsl:copy-of select="statement"/>
|
|
1276
|
-
<!-- skip over response until it carries something relevant -->
|
|
1277
|
-
<xsl:copy-of select="hint"/>
|
|
1278
|
-
<xsl:copy-of select="answer"/>
|
|
1279
|
-
<xsl:copy-of select="solution"/>
|
|
1280
|
-
</xsl:template>
|
|
1281
|
-
|
|
1282
|
-
<!-- Queries -->
|
|
1283
|
-
|
|
1284
|
-
<xsl:template match="query" mode="runestone-to-static">
|
|
1285
|
-
<paragraphs>
|
|
1286
|
-
<!-- no period, it is supplied by conversions -->
|
|
1287
|
-
<title>
|
|
1288
|
-
<xsl:element name="pi:localize">
|
|
1289
|
-
<xsl:attribute name="string-id">query</xsl:attribute>
|
|
1290
|
-
</xsl:element>
|
|
1291
|
-
</title>
|
|
1292
|
-
<!-- reproduce structured statement's pieces -->
|
|
1293
|
-
<xsl:copy-of select="statement/*"/>
|
|
1294
|
-
<xsl:choose>
|
|
1295
|
-
<xsl:when test="choices">
|
|
1296
|
-
<p><ol format="1.">
|
|
1297
|
-
<xsl:for-each select="choices/choice">
|
|
1298
|
-
<li>
|
|
1299
|
-
<xsl:copy-of select="."/>
|
|
1300
|
-
</li>
|
|
1301
|
-
</xsl:for-each>
|
|
1302
|
-
</ol></p>
|
|
1303
|
-
</xsl:when>
|
|
1304
|
-
<xsl:when test="@scale">
|
|
1305
|
-
<!-- A pre-formatted "display" of the integer choices, -->
|
|
1306
|
-
<!-- which could be printed and circled by the reader. -->
|
|
1307
|
-
<pre>
|
|
1308
|
-
<xsl:apply-templates select="." mode="scale-choices"/>
|
|
1309
|
-
</pre>
|
|
1310
|
-
</xsl:when>
|
|
1311
|
-
<xsl:otherwise/>
|
|
1312
|
-
</xsl:choose>
|
|
1313
|
-
</paragraphs>
|
|
1314
|
-
</xsl:template>
|
|
1315
|
-
|
|
1316
|
-
<!-- Recursively count-up and layout choices with rows of -->
|
|
1317
|
-
<!-- 10 choices each, with blank lines between the rows. -->
|
|
1318
|
-
<xsl:template match="query" mode="scale-choices">
|
|
1319
|
-
<xsl:param name="the-choice" select="'1'"/>
|
|
1320
|
-
|
|
1321
|
-
<xsl:choose>
|
|
1322
|
-
<!-- Done. Emit and that's it -->
|
|
1323
|
-
<xsl:when test="$the-choice = ./@scale">
|
|
1324
|
-
<xsl:value-of select="$the-choice"/>
|
|
1325
|
-
</xsl:when>
|
|
1326
|
-
<!-- Done with a row, but not done. Newline, and blankline. -->
|
|
1327
|
-
<xsl:when test="$the-choice mod 10 = 0">
|
|
1328
|
-
<xsl:value-of select="$the-choice"/>
|
|
1329
|
-
<xsl:text>

</xsl:text>
|
|
1330
|
-
<xsl:apply-templates select="." mode="scale-choices">
|
|
1331
|
-
<xsl:with-param name="the-choice" select="$the-choice + 1"/>
|
|
1332
|
-
</xsl:apply-templates>
|
|
1333
|
-
</xsl:when>
|
|
1334
|
-
<!-- Mid-row, use two spaces to separate. -->
|
|
1335
|
-
<xsl:otherwise>
|
|
1336
|
-
<xsl:value-of select="$the-choice"/>
|
|
1337
|
-
<xsl:text>  </xsl:text>
|
|
1338
|
-
<xsl:apply-templates select="." mode="scale-choices">
|
|
1339
|
-
<xsl:with-param name="the-choice" select="$the-choice + 1"/>
|
|
1340
|
-
</xsl:apply-templates>
|
|
1341
|
-
</xsl:otherwise>
|
|
1342
|
-
</xsl:choose>
|
|
1343
|
-
</xsl:template>
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
<!-- Active Code -->
|
|
1347
|
-
|
|
1348
|
-
<xsl:template match="*[@exercise-interactive = 'coding']" mode="runestone-to-static">
|
|
1349
|
-
<!-- metadata (idx, title) -->
|
|
1350
|
-
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
1351
|
-
<statement>
|
|
1352
|
-
<!-- duplicate the authored prompt/statement -->
|
|
1353
|
-
<xsl:copy-of select="statement/node()"/>
|
|
1354
|
-
<!-- Bring up the program as part of the problem statement and -->
|
|
1355
|
-
<!-- also neuter any @interactive indication. This was not -->
|
|
1356
|
-
<!-- tagged as a coding exercise without a "program" outside -->
|
|
1357
|
-
<!-- the "statement", but we are careful about not making an -->
|
|
1358
|
-
<!-- empty "program" where there is none. -->
|
|
1359
|
-
<xsl:if test="program">
|
|
1360
|
-
<xsl:element name="program">
|
|
1361
|
-
<xsl:copy-of select="program/@*[not(name() = 'interactive')]"/>
|
|
1362
|
-
<xsl:copy-of select="program/node()"/>
|
|
1363
|
-
</xsl:element>
|
|
1364
|
-
</xsl:if>
|
|
1365
|
-
</statement>
|
|
1366
|
-
<xsl:copy-of select="hint"/>
|
|
1367
|
-
<xsl:copy-of select="answer"/>
|
|
1368
|
-
<xsl:copy-of select="solution"/>
|
|
1369
|
-
</xsl:template>
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
<xsl:template match="datafile" mode="runestone-to-static">
|
|
1373
|
-
<!-- Some templates and variables are defined in -common for consistency -->
|
|
1374
|
-
|
|
1375
|
-
<!-- Mostly the data file is a "pre", or an "image", but we -->
|
|
1376
|
-
<!-- want to have a title of sorts indicating the filename. -->
|
|
1377
|
-
<!-- To accomplish an overall element that won't disrupt -->
|
|
1378
|
-
<!-- subsequent automatic ids, we do a bit of a hack: a -->
|
|
1379
|
-
<!-- "sidebyside" as the overall element with a "stack". -->
|
|
1380
|
-
<sidebyside>
|
|
1381
|
-
<stack>
|
|
1382
|
-
<!-- faux title -->
|
|
1383
|
-
<p>
|
|
1384
|
-
<xsl:element name="pi:localize">
|
|
1385
|
-
<xsl:attribute name="string-id">data</xsl:attribute>
|
|
1386
|
-
</xsl:element>
|
|
1387
|
-
<xsl:text>: </xsl:text>
|
|
1388
|
-
<c>
|
|
1389
|
-
<xsl:value-of select="@filename"/>
|
|
1390
|
-
</c>
|
|
1391
|
-
</p>
|
|
1392
|
-
<!-- image or code, one panel -->
|
|
1393
|
-
<xsl:choose>
|
|
1394
|
-
<xsl:when test="image">
|
|
1395
|
-
<xsl:copy-of select="image"/>
|
|
1396
|
-
</xsl:when>
|
|
1397
|
-
<xsl:when test="pre">
|
|
1398
|
-
<!-- provide default rows and cols, sync with dynamic version -->
|
|
1399
|
-
<xsl:variable name="desired-rows">
|
|
1400
|
-
<xsl:choose>
|
|
1401
|
-
<xsl:when test="@rows">
|
|
1402
|
-
<xsl:value-of select="@rows"/>
|
|
1403
|
-
</xsl:when>
|
|
1404
|
-
<xsl:otherwise>
|
|
1405
|
-
<xsl:value-of select="$datafile-default-rows"/>
|
|
1406
|
-
</xsl:otherwise>
|
|
1407
|
-
</xsl:choose>
|
|
1408
|
-
</xsl:variable>
|
|
1409
|
-
<xsl:variable name="desired-cols">
|
|
1410
|
-
<xsl:choose>
|
|
1411
|
-
<xsl:when test="@cols">
|
|
1412
|
-
<xsl:value-of select="@cols"/>
|
|
1413
|
-
</xsl:when>
|
|
1414
|
-
<xsl:otherwise>
|
|
1415
|
-
<xsl:value-of select="$datafile-default-cols"/>
|
|
1416
|
-
</xsl:otherwise>
|
|
1417
|
-
</xsl:choose>
|
|
1418
|
-
</xsl:variable>
|
|
1419
|
-
<pre>
|
|
1420
|
-
<!-- form an "upper-left-corner" view -->
|
|
1421
|
-
<xsl:call-template name="text-viewport">
|
|
1422
|
-
<xsl:with-param name="nrows" select="$desired-rows"/>
|
|
1423
|
-
<xsl:with-param name="ncols" select="$desired-cols"/>
|
|
1424
|
-
<xsl:with-param name="text">
|
|
1425
|
-
<!-- defined in -common -->
|
|
1426
|
-
<xsl:apply-templates select="." mode="datafile-text-contents"/>
|
|
1427
|
-
</xsl:with-param>
|
|
1428
|
-
</xsl:call-template>
|
|
1429
|
-
</pre>
|
|
1430
|
-
</xsl:when>
|
|
1431
|
-
<!-- no other source/PTX element is supported , bail out-->
|
|
1432
|
-
<xsl:otherwise/>
|
|
1433
|
-
</xsl:choose>
|
|
1434
|
-
</stack>
|
|
1435
|
-
</sidebyside>
|
|
1436
|
-
</xsl:template>
|
|
1437
|
-
|
|
1438
|
-
</xsl:stylesheet>
|
|
1
|
+
<?xml version='1.0'?> <!-- As XML file -->
|
|
2
|
+
|
|
3
|
+
<!--********************************************************************
|
|
4
|
+
Copyright 2022 Robert A. Beezer
|
|
5
|
+
|
|
6
|
+
This file is part of PreTeXt.
|
|
7
|
+
|
|
8
|
+
PreTeXt is free software: you can redistribute it and/or modify
|
|
9
|
+
it under the terms of the GNU General Public License as published by
|
|
10
|
+
the Free Software Foundation, either version 2 or version 3 of the
|
|
11
|
+
License (at your option).
|
|
12
|
+
|
|
13
|
+
PreTeXt is distributed in the hope that it will be useful,
|
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
You should have received a copy of the GNU General Public License
|
|
19
|
+
along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
*********************************************************************-->
|
|
21
|
+
|
|
22
|
+
<!-- http://pimpmyxslt.com/articles/entity-tricks-part2/ -->
|
|
23
|
+
<!DOCTYPE xsl:stylesheet [
|
|
24
|
+
<!ENTITY % entities SYSTEM "entities.ent">
|
|
25
|
+
%entities;
|
|
26
|
+
]>
|
|
27
|
+
|
|
28
|
+
<xsl:stylesheet
|
|
29
|
+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
|
|
30
|
+
xmlns:xml="http://www.w3.org/XML/1998/namespace"
|
|
31
|
+
xmlns:pi="http://pretextbook.org/2020/pretext/internal"
|
|
32
|
+
xmlns:exsl="http://exslt.org/common"
|
|
33
|
+
xmlns:str="http://exslt.org/strings"
|
|
34
|
+
extension-element-prefixes="pi exsl str"
|
|
35
|
+
>
|
|
36
|
+
|
|
37
|
+
<!-- Conversion of author source for Runestone/interactive exercises -->
|
|
38
|
+
<!-- to "standard" PreTeXt exercises, which can be used as-is in -->
|
|
39
|
+
<!-- *every* conversion, except the HTML conversion, where a more -->
|
|
40
|
+
<!-- capable version is designed to be powered by Runestone Services. -->
|
|
41
|
+
|
|
42
|
+
<!-- We include text utilities so we can manipulate indentation -->
|
|
43
|
+
<!-- in blocks of code as part of Parsons problems -->
|
|
44
|
+
<xsl:include href = "./pretext-text-utilities.xsl"/>
|
|
45
|
+
|
|
46
|
+
<!-- The enclosing "exercise" and its attributes are preserved -->
|
|
47
|
+
<!-- before these templates are applied, so these should just -->
|
|
48
|
+
<!-- produce the "body" of the exercise. -->
|
|
49
|
+
|
|
50
|
+
<!-- The application of the "runestone-to-static" template is -->
|
|
51
|
+
<!-- controlled by a surrounding "match" that limits elements -->
|
|
52
|
+
<!-- to "exercise", PROJECT-LIKE, and soon "task". So the -->
|
|
53
|
+
<!-- matches here are fine with a *[@exercise-interactive='foo'], -->
|
|
54
|
+
<!-- as a convenience. -->
|
|
55
|
+
|
|
56
|
+
<!-- These get-programming-language templates duplicate logic from pretext-common -->
|
|
57
|
+
<!-- as the contents of that file are not available yet. -->
|
|
58
|
+
<xsl:template match="program" mode="get-programming-language">
|
|
59
|
+
<xsl:choose>
|
|
60
|
+
<xsl:when test="@language">
|
|
61
|
+
<xsl:value-of select="@language" />
|
|
62
|
+
</xsl:when>
|
|
63
|
+
<xsl:when test="$version-docinfo/programs/@language">
|
|
64
|
+
<xsl:value-of select="$version-docinfo/programs/@language" />
|
|
65
|
+
</xsl:when>
|
|
66
|
+
</xsl:choose>
|
|
67
|
+
</xsl:template>
|
|
68
|
+
|
|
69
|
+
<xsl:template match="*[@exercise-interactive = 'parson' or @exercise-interactive = 'parson-horizontal']" mode="get-programming-language">
|
|
70
|
+
<xsl:choose>
|
|
71
|
+
<xsl:when test="@language">
|
|
72
|
+
<xsl:value-of select="@language" />
|
|
73
|
+
</xsl:when>
|
|
74
|
+
<xsl:when test="$version-docinfo/parsons/@language">
|
|
75
|
+
<xsl:value-of select="$version-docinfo/parsons/@language" />
|
|
76
|
+
</xsl:when>
|
|
77
|
+
<xsl:when test="$version-docinfo/programs/@language">
|
|
78
|
+
<xsl:value-of select="$version-docinfo/programs/@language" />
|
|
79
|
+
</xsl:when>
|
|
80
|
+
</xsl:choose>
|
|
81
|
+
</xsl:template>
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
<!-- True/False -->
|
|
85
|
+
|
|
86
|
+
<xsl:template match="*[@exercise-interactive = 'truefalse']" mode="runestone-to-static">
|
|
87
|
+
<!-- metadata (idx, title) -->
|
|
88
|
+
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
89
|
+
<!-- prompt, followed by ordered list of choices -->
|
|
90
|
+
<statement>
|
|
91
|
+
<xsl:copy-of select="statement/node()"/>
|
|
92
|
+
</statement>
|
|
93
|
+
<!-- Hints are authored, not derived from problem formulation -->
|
|
94
|
+
<xsl:copy-of select="hint"/>
|
|
95
|
+
<!-- Any authored answers, not derived from problem formulation. -->
|
|
96
|
+
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
97
|
+
<!-- versions on authored ones. -->
|
|
98
|
+
<xsl:copy-of select="answer"/>
|
|
99
|
+
<!-- the answer, simply "True" or "False" -->
|
|
100
|
+
<answer>
|
|
101
|
+
<xsl:choose>
|
|
102
|
+
<xsl:when test="statement/@correct = 'yes'">
|
|
103
|
+
<p>
|
|
104
|
+
<xsl:element name="pi:localize">
|
|
105
|
+
<xsl:attribute name="string-id">true</xsl:attribute>
|
|
106
|
+
</xsl:element>
|
|
107
|
+
<xsl:text>.</xsl:text>
|
|
108
|
+
</p>
|
|
109
|
+
</xsl:when>
|
|
110
|
+
<xsl:when test="statement/@correct = 'no'">
|
|
111
|
+
<p>
|
|
112
|
+
<xsl:element name="pi:localize">
|
|
113
|
+
<xsl:attribute name="string-id">false</xsl:attribute>
|
|
114
|
+
</xsl:element>
|
|
115
|
+
<xsl:text>.</xsl:text>
|
|
116
|
+
</p>
|
|
117
|
+
</xsl:when>
|
|
118
|
+
<xsl:otherwise/>
|
|
119
|
+
</xsl:choose>
|
|
120
|
+
</answer>
|
|
121
|
+
<!-- Any authored solutions, not derived from problem formulation. -->
|
|
122
|
+
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
123
|
+
<!-- versions on authored ones. -->
|
|
124
|
+
<xsl:copy-of select="solution"/>
|
|
125
|
+
<!-- Answer, as above, plus explication with feedback -->
|
|
126
|
+
<!-- TODO: experiment with a one-item "dl" for a slightly more -->
|
|
127
|
+
<!-- appealing presentation, rather than a one-word paragraph. -->
|
|
128
|
+
<solution>
|
|
129
|
+
<xsl:choose>
|
|
130
|
+
<xsl:when test="statement/@correct = 'yes'">
|
|
131
|
+
<p>
|
|
132
|
+
<xsl:element name="pi:localize">
|
|
133
|
+
<xsl:attribute name="string-id">true</xsl:attribute>
|
|
134
|
+
</xsl:element>
|
|
135
|
+
<xsl:text>.</xsl:text>
|
|
136
|
+
</p>
|
|
137
|
+
</xsl:when>
|
|
138
|
+
<xsl:when test="statement/@correct = 'no'">
|
|
139
|
+
<p>
|
|
140
|
+
<xsl:element name="pi:localize">
|
|
141
|
+
<xsl:attribute name="string-id">false</xsl:attribute>
|
|
142
|
+
</xsl:element>
|
|
143
|
+
<xsl:text>.</xsl:text>
|
|
144
|
+
</p>
|
|
145
|
+
</xsl:when>
|
|
146
|
+
<xsl:otherwise/>
|
|
147
|
+
</xsl:choose>
|
|
148
|
+
<xsl:copy-of select="feedback/node()"/>
|
|
149
|
+
</solution>
|
|
150
|
+
</xsl:template>
|
|
151
|
+
|
|
152
|
+
<xsl:template match="*[@exercise-interactive = 'multiplechoice']" mode="runestone-to-static">
|
|
153
|
+
<!-- metadata (idx, title) -->
|
|
154
|
+
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
155
|
+
<!-- prompt, followed by ordered list of choices -->
|
|
156
|
+
<statement>
|
|
157
|
+
<xsl:copy-of select="statement/node()"/>
|
|
158
|
+
<p><ol marker="A."> <!-- conforms to RS markers -->
|
|
159
|
+
<!-- duplicate an optional @cols -->
|
|
160
|
+
<xsl:copy-of select="choices/@cols"/>
|
|
161
|
+
<xsl:for-each select="choices/choice">
|
|
162
|
+
<li>
|
|
163
|
+
<xsl:copy-of select="statement/node()"/>
|
|
164
|
+
</li>
|
|
165
|
+
</xsl:for-each>
|
|
166
|
+
</ol></p>
|
|
167
|
+
</statement>
|
|
168
|
+
<!-- Hints are authored, not derived from problem formulation -->
|
|
169
|
+
<xsl:copy-of select="hint"/>
|
|
170
|
+
<!-- Any authored answers, not derived from problem formulation. -->
|
|
171
|
+
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
172
|
+
<!-- versions on authored ones. -->
|
|
173
|
+
<xsl:copy-of select="answer"/>
|
|
174
|
+
<!-- the correct choices, as letters, in a sentence as a list -->
|
|
175
|
+
<answer>
|
|
176
|
+
<p>
|
|
177
|
+
<xsl:for-each select="choices/choice">
|
|
178
|
+
<xsl:if test="@correct = 'yes'">
|
|
179
|
+
<xsl:number format="A"/>
|
|
180
|
+
<xsl:if test="following-sibling::choice[@correct = 'yes']">
|
|
181
|
+
<xsl:text>, </xsl:text>
|
|
182
|
+
</xsl:if>
|
|
183
|
+
</xsl:if>
|
|
184
|
+
</xsl:for-each>
|
|
185
|
+
<xsl:text>.</xsl:text>
|
|
186
|
+
</p>
|
|
187
|
+
</answer>
|
|
188
|
+
<!-- Any authored solutions, not derived from problem formulation. -->
|
|
189
|
+
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
190
|
+
<!-- versions on authored ones. -->
|
|
191
|
+
<xsl:copy-of select="solution"/>
|
|
192
|
+
<!-- feedback for each choice, in a list -->
|
|
193
|
+
<solution>
|
|
194
|
+
<p><ol marker="A."> <!-- conforms to RS markers -->
|
|
195
|
+
<xsl:for-each select="choices/choice">
|
|
196
|
+
<li>
|
|
197
|
+
<title>
|
|
198
|
+
<xsl:choose>
|
|
199
|
+
<xsl:when test="@correct = 'yes'">
|
|
200
|
+
<xsl:element name="pi:localize">
|
|
201
|
+
<xsl:attribute name="string-id">correct</xsl:attribute>
|
|
202
|
+
</xsl:element>
|
|
203
|
+
</xsl:when>
|
|
204
|
+
<xsl:otherwise>
|
|
205
|
+
<xsl:element name="pi:localize">
|
|
206
|
+
<xsl:attribute name="string-id">incorrect</xsl:attribute>
|
|
207
|
+
</xsl:element>
|
|
208
|
+
</xsl:otherwise>
|
|
209
|
+
</xsl:choose>
|
|
210
|
+
</title>
|
|
211
|
+
<xsl:copy-of select="feedback/node()"/>
|
|
212
|
+
</li>
|
|
213
|
+
</xsl:for-each>
|
|
214
|
+
</ol></p>
|
|
215
|
+
</solution>
|
|
216
|
+
</xsl:template>
|
|
217
|
+
|
|
218
|
+
<xsl:template match="*[@exercise-interactive = 'parson']" mode="runestone-to-static">
|
|
219
|
+
<!-- determine these options before context switches -->
|
|
220
|
+
<xsl:variable name="language">
|
|
221
|
+
<!-- we just need the "raw" programming language, not active-language translation -->
|
|
222
|
+
<xsl:apply-templates select="." mode="get-programming-language"/>
|
|
223
|
+
</xsl:variable>
|
|
224
|
+
<xsl:variable name="b-natural" select="($language = '') or ($language = 'natural')"/>
|
|
225
|
+
<xsl:attribute name="language">
|
|
226
|
+
<xsl:value-of select="$language"/>
|
|
227
|
+
</xsl:attribute>
|
|
228
|
+
<!-- default for @indentation is "show", regards presentation -->
|
|
229
|
+
<xsl:variable name="b-indent" select="@indentation = 'hide'"/>
|
|
230
|
+
<!-- we use numbers in static versions, if requested, but ignore left/right distinction -->
|
|
231
|
+
<!-- default for @numbered is "no" -->
|
|
232
|
+
<!-- do not confuse this attribute with the @pi:numbered attribute for numbered equations -->
|
|
233
|
+
<xsl:variable name="b-numbered" select="(blocks/@numbered = 'left') or (blocks/@numbered = 'right')"/>
|
|
234
|
+
<!-- metadata (idx, title) -->
|
|
235
|
+
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
236
|
+
<!-- Statement -->
|
|
237
|
+
<statement>
|
|
238
|
+
<xsl:copy-of select="statement/node()"/>
|
|
239
|
+
<xsl:variable name="list-type">
|
|
240
|
+
<xsl:choose>
|
|
241
|
+
<xsl:when test="$b-numbered">
|
|
242
|
+
<xsl:text>ol</xsl:text>
|
|
243
|
+
</xsl:when>
|
|
244
|
+
<xsl:otherwise>
|
|
245
|
+
<xsl:text>ul</xsl:text>
|
|
246
|
+
</xsl:otherwise>
|
|
247
|
+
</xsl:choose>
|
|
248
|
+
</xsl:variable>
|
|
249
|
+
<!-- blocks, in author-defined order, via @order attribute -->
|
|
250
|
+
<p>
|
|
251
|
+
<xsl:element name="{$list-type}">
|
|
252
|
+
<xsl:if test="$list-type = 'ol'">
|
|
253
|
+
<xsl:attribute name="marker">
|
|
254
|
+
<xsl:text>1.</xsl:text>
|
|
255
|
+
</xsl:attribute>
|
|
256
|
+
</xsl:if>
|
|
257
|
+
<xsl:for-each select="blocks/block">
|
|
258
|
+
<xsl:sort select="@order"/>
|
|
259
|
+
<li>
|
|
260
|
+
<xsl:choose>
|
|
261
|
+
<xsl:when test="choice">
|
|
262
|
+
<!-- a paired distractor in the block -->
|
|
263
|
+
<!-- separate alternatives with "Either/Or" -->
|
|
264
|
+
<!-- Order is as authored -->
|
|
265
|
+
<xsl:element name="{$list-type}">
|
|
266
|
+
<xsl:attribute name="marker">
|
|
267
|
+
<xsl:choose>
|
|
268
|
+
<xsl:when test="$list-type = 'ol'">
|
|
269
|
+
<!-- sub-number as a, b, c -->
|
|
270
|
+
<xsl:text>(a)</xsl:text>
|
|
271
|
+
</xsl:when>
|
|
272
|
+
<xsl:when test="$list-type = 'ul'">
|
|
273
|
+
<!-- no markers on "bulleted" sublists -->
|
|
274
|
+
<xsl:text/>
|
|
275
|
+
</xsl:when>
|
|
276
|
+
</xsl:choose>
|
|
277
|
+
</xsl:attribute>
|
|
278
|
+
<xsl:for-each select="choice">
|
|
279
|
+
<li>
|
|
280
|
+
<xsl:if test="$list-type = 'ul'">
|
|
281
|
+
<xsl:choose>
|
|
282
|
+
<xsl:when test="not(preceding-sibling::choice)">
|
|
283
|
+
<p>
|
|
284
|
+
<xsl:element name="pi:localize">
|
|
285
|
+
<xsl:attribute name="string-id">either</xsl:attribute>
|
|
286
|
+
</xsl:element>
|
|
287
|
+
<xsl:text>:</xsl:text>
|
|
288
|
+
</p>
|
|
289
|
+
</xsl:when>
|
|
290
|
+
<xsl:otherwise>
|
|
291
|
+
<p>
|
|
292
|
+
<xsl:element name="pi:localize">
|
|
293
|
+
<xsl:attribute name="string-id">or</xsl:attribute>
|
|
294
|
+
</xsl:element>
|
|
295
|
+
<xsl:text>:</xsl:text>
|
|
296
|
+
</p>
|
|
297
|
+
</xsl:otherwise>
|
|
298
|
+
</xsl:choose>
|
|
299
|
+
</xsl:if>
|
|
300
|
+
<xsl:choose>
|
|
301
|
+
<xsl:when test="$b-natural">
|
|
302
|
+
<!-- replicate source of choice -->
|
|
303
|
+
<xsl:copy-of select="node()"/>
|
|
304
|
+
</xsl:when>
|
|
305
|
+
<xsl:otherwise>
|
|
306
|
+
<!-- computer code, make a code display -->
|
|
307
|
+
<!-- A "p" gets indentation relative to Either/Or -->
|
|
308
|
+
<!-- Otherwsie, we could make a sublist? -->
|
|
309
|
+
<p>
|
|
310
|
+
<cd>
|
|
311
|
+
<xsl:choose>
|
|
312
|
+
<xsl:when test="$b-indent">
|
|
313
|
+
<xsl:apply-templates select="." mode="strip-cline-indentation"/>
|
|
314
|
+
</xsl:when>
|
|
315
|
+
<xsl:otherwise>
|
|
316
|
+
<xsl:copy-of select="node()"/>
|
|
317
|
+
</xsl:otherwise>
|
|
318
|
+
</xsl:choose>
|
|
319
|
+
</cd>
|
|
320
|
+
</p>
|
|
321
|
+
</xsl:otherwise>
|
|
322
|
+
</xsl:choose>
|
|
323
|
+
</li>
|
|
324
|
+
</xsl:for-each>
|
|
325
|
+
</xsl:element>
|
|
326
|
+
</xsl:when>
|
|
327
|
+
<xsl:otherwise>
|
|
328
|
+
<!-- not a paired distractor -->
|
|
329
|
+
<xsl:choose>
|
|
330
|
+
<xsl:when test="$b-natural">
|
|
331
|
+
<!-- replicate source of block -->
|
|
332
|
+
<xsl:copy-of select="node()"/>
|
|
333
|
+
</xsl:when>
|
|
334
|
+
<xsl:otherwise>
|
|
335
|
+
<!-- computer code, make a code display -->
|
|
336
|
+
<cd>
|
|
337
|
+
<xsl:choose>
|
|
338
|
+
<xsl:when test="$b-indent">
|
|
339
|
+
<!-- a hard problem, reader supplies indentation -->
|
|
340
|
+
<xsl:apply-templates select="." mode="strip-cline-indentation"/>
|
|
341
|
+
</xsl:when>
|
|
342
|
+
<xsl:otherwise>
|
|
343
|
+
<!-- a little help, indentation preserved and visible -->
|
|
344
|
+
<xsl:attribute name="showspaces">
|
|
345
|
+
<xsl:text>all</xsl:text>
|
|
346
|
+
</xsl:attribute>
|
|
347
|
+
<xsl:text>
</xsl:text>
|
|
348
|
+
<xsl:copy-of select="node()"/>
|
|
349
|
+
</xsl:otherwise>
|
|
350
|
+
</xsl:choose>
|
|
351
|
+
</cd>
|
|
352
|
+
</xsl:otherwise>
|
|
353
|
+
</xsl:choose>
|
|
354
|
+
</xsl:otherwise>
|
|
355
|
+
</xsl:choose>
|
|
356
|
+
</li>
|
|
357
|
+
</xsl:for-each>
|
|
358
|
+
</xsl:element>
|
|
359
|
+
</p>
|
|
360
|
+
</statement>
|
|
361
|
+
<!-- Any authored answers, not derived from problem formulation. -->
|
|
362
|
+
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
363
|
+
<!-- versions on authored ones. -->
|
|
364
|
+
<xsl:copy-of select="answer"/>
|
|
365
|
+
<!-- Answer (potentially) -->
|
|
366
|
+
<xsl:if test="$b-numbered">
|
|
367
|
+
<!-- can make an economical answer with numbers of the -->
|
|
368
|
+
<!-- (correct) blocks in the order of the solution -->
|
|
369
|
+
<answer>
|
|
370
|
+
<p>
|
|
371
|
+
<xsl:for-each select="blocks/block">
|
|
372
|
+
<!-- default on "block" is correct="yes" -->
|
|
373
|
+
<xsl:if test="not(@correct = 'no')">
|
|
374
|
+
<xsl:value-of select="@order"/>
|
|
375
|
+
<xsl:if test="choice">
|
|
376
|
+
<xsl:for-each select="choice">
|
|
377
|
+
<!-- default on "choice" is correct="no" -->
|
|
378
|
+
<xsl:if test="@correct = 'yes'">
|
|
379
|
+
<xsl:number format="a"/>
|
|
380
|
+
</xsl:if>
|
|
381
|
+
</xsl:for-each>
|
|
382
|
+
</xsl:if>
|
|
383
|
+
<xsl:if test="following-sibling::block">
|
|
384
|
+
<xsl:text>, </xsl:text>
|
|
385
|
+
</xsl:if>
|
|
386
|
+
</xsl:if>
|
|
387
|
+
</xsl:for-each>
|
|
388
|
+
</p>
|
|
389
|
+
</answer>
|
|
390
|
+
</xsl:if>
|
|
391
|
+
<!-- Any authored solutions, not derived from problem formulation. -->
|
|
392
|
+
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
393
|
+
<!-- versions on authored ones. -->
|
|
394
|
+
<xsl:copy-of select="solution"/>
|
|
395
|
+
<!-- Solution -->
|
|
396
|
+
<solution>
|
|
397
|
+
<xsl:choose>
|
|
398
|
+
<xsl:when test="$b-natural">
|
|
399
|
+
<!-- not a programming exercise, use unordered -->
|
|
400
|
+
<!-- or description list and copy "natural" markup -->
|
|
401
|
+
<xsl:variable name="list-type">
|
|
402
|
+
<xsl:choose>
|
|
403
|
+
<xsl:when test="$b-numbered">
|
|
404
|
+
<xsl:text>dl</xsl:text>
|
|
405
|
+
</xsl:when>
|
|
406
|
+
<xsl:otherwise>
|
|
407
|
+
<xsl:text>ul</xsl:text>
|
|
408
|
+
</xsl:otherwise>
|
|
409
|
+
</xsl:choose>
|
|
410
|
+
</xsl:variable>
|
|
411
|
+
<p>
|
|
412
|
+
<xsl:element name="{$list-type}">
|
|
413
|
+
<xsl:if test="$list-type = 'dl'">
|
|
414
|
+
<xsl:attribute name="width">
|
|
415
|
+
<xsl:text>narrow</xsl:text>
|
|
416
|
+
</xsl:attribute>
|
|
417
|
+
</xsl:if>
|
|
418
|
+
<xsl:for-each select="blocks/block">
|
|
419
|
+
<!-- default on "block" is correct="yes" -->
|
|
420
|
+
<xsl:if test="not(@correct = 'no')">
|
|
421
|
+
<li>
|
|
422
|
+
<xsl:if test="$list-type = 'dl'">
|
|
423
|
+
<title>
|
|
424
|
+
<xsl:value-of select="@order"/>
|
|
425
|
+
<xsl:if test="choice">
|
|
426
|
+
<xsl:for-each select="choice">
|
|
427
|
+
<!-- default on "choice" is correct="no" -->
|
|
428
|
+
<xsl:if test="@correct = 'yes'">
|
|
429
|
+
<xsl:number format="a"/>
|
|
430
|
+
</xsl:if>
|
|
431
|
+
</xsl:for-each>
|
|
432
|
+
</xsl:if>
|
|
433
|
+
</title>
|
|
434
|
+
</xsl:if>
|
|
435
|
+
<xsl:choose>
|
|
436
|
+
<xsl:when test="choice">
|
|
437
|
+
<!-- just the correct one -->
|
|
438
|
+
<xsl:for-each select="choice">
|
|
439
|
+
<xsl:if test="@correct = 'yes'">
|
|
440
|
+
<xsl:copy-of select="node()"/>
|
|
441
|
+
</xsl:if>
|
|
442
|
+
</xsl:for-each>
|
|
443
|
+
</xsl:when>
|
|
444
|
+
<xsl:otherwise>
|
|
445
|
+
<xsl:copy-of select="node()"/>
|
|
446
|
+
</xsl:otherwise>
|
|
447
|
+
</xsl:choose>
|
|
448
|
+
</li>
|
|
449
|
+
</xsl:if>
|
|
450
|
+
</xsl:for-each>
|
|
451
|
+
</xsl:element>
|
|
452
|
+
</p>
|
|
453
|
+
</xsl:when>
|
|
454
|
+
<xsl:otherwise>
|
|
455
|
+
<!-- programming language specified, assume "cline" -->
|
|
456
|
+
<!-- structure, reconstruct as a program/input -->
|
|
457
|
+
<program>
|
|
458
|
+
<xsl:attribute name="language">
|
|
459
|
+
<xsl:value-of select="$language"/>
|
|
460
|
+
</xsl:attribute>
|
|
461
|
+
<input>
|
|
462
|
+
<xsl:for-each select="blocks/block">
|
|
463
|
+
<xsl:if test="not(@correct = 'no')">
|
|
464
|
+
<xsl:choose>
|
|
465
|
+
<xsl:when test="choice">
|
|
466
|
+
<!-- just the correct choice -->
|
|
467
|
+
<!-- default on "choice" is correct="no" -->
|
|
468
|
+
<xsl:for-each select="choice">
|
|
469
|
+
<xsl:if test="@correct = 'yes'">
|
|
470
|
+
<xsl:for-each select="cline">
|
|
471
|
+
<xsl:value-of select="."/>
|
|
472
|
+
<xsl:text>
</xsl:text>
|
|
473
|
+
</xsl:for-each>
|
|
474
|
+
</xsl:if>
|
|
475
|
+
</xsl:for-each>
|
|
476
|
+
</xsl:when>
|
|
477
|
+
<xsl:otherwise>
|
|
478
|
+
<xsl:for-each select="cline">
|
|
479
|
+
<xsl:value-of select="."/>
|
|
480
|
+
<xsl:text>
</xsl:text>
|
|
481
|
+
</xsl:for-each>
|
|
482
|
+
</xsl:otherwise>
|
|
483
|
+
</xsl:choose>
|
|
484
|
+
</xsl:if>
|
|
485
|
+
</xsl:for-each>
|
|
486
|
+
</input>
|
|
487
|
+
</program>
|
|
488
|
+
</xsl:otherwise>
|
|
489
|
+
</xsl:choose>
|
|
490
|
+
</solution>
|
|
491
|
+
</xsl:template>
|
|
492
|
+
|
|
493
|
+
<!-- If a sequence of "cline" are in a problem where a student does -->
|
|
494
|
+
<!-- not get indentation help, then we need to strip it out for -->
|
|
495
|
+
<!-- presentation in a static form. This template forms the text block, -->
|
|
496
|
+
<!-- strips leading/gross indentation with a utility template, then uses -->
|
|
497
|
+
<!-- a recursive template to wrap back into "cline". -->
|
|
498
|
+
|
|
499
|
+
<xsl:template match="block|choice" mode="strip-cline-indentation">
|
|
500
|
+
<xsl:variable name="text-block">
|
|
501
|
+
<xsl:for-each select="cline">
|
|
502
|
+
<xsl:value-of select="."/>
|
|
503
|
+
<xsl:text>
</xsl:text>
|
|
504
|
+
</xsl:for-each>
|
|
505
|
+
</xsl:variable>
|
|
506
|
+
<xsl:call-template name="restore-cline">
|
|
507
|
+
<xsl:with-param name="text">
|
|
508
|
+
<xsl:call-template name="sanitize-text">
|
|
509
|
+
<xsl:with-param name="text">
|
|
510
|
+
<xsl:value-of select="$text-block"/>
|
|
511
|
+
</xsl:with-param>
|
|
512
|
+
</xsl:call-template>
|
|
513
|
+
</xsl:with-param>
|
|
514
|
+
</xsl:call-template>
|
|
515
|
+
</xsl:template>
|
|
516
|
+
|
|
517
|
+
<xsl:template name="restore-cline">
|
|
518
|
+
<xsl:param name="text"/>
|
|
519
|
+
|
|
520
|
+
<xsl:choose>
|
|
521
|
+
<xsl:when test="$text = ''"/>
|
|
522
|
+
<xsl:otherwise>
|
|
523
|
+
<cline>
|
|
524
|
+
<xsl:value-of select="substring-before($text, '
')"/>
|
|
525
|
+
</cline>
|
|
526
|
+
<xsl:call-template name="restore-cline">
|
|
527
|
+
<xsl:with-param name="text" select="substring-after($text, '
')"/>
|
|
528
|
+
</xsl:call-template>
|
|
529
|
+
</xsl:otherwise>
|
|
530
|
+
</xsl:choose>
|
|
531
|
+
</xsl:template>
|
|
532
|
+
|
|
533
|
+
<!-- Parson (Horizontal) -->
|
|
534
|
+
|
|
535
|
+
<xsl:template match="*[@exercise-interactive = 'parson-horizontal']" mode="runestone-to-static">
|
|
536
|
+
<xsl:attribute name="language">
|
|
537
|
+
<xsl:apply-templates select="." mode="active-language"/>
|
|
538
|
+
</xsl:attribute>
|
|
539
|
+
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
540
|
+
<!-- Statement -->
|
|
541
|
+
<statement>
|
|
542
|
+
<xsl:copy-of select="statement/node()"/>
|
|
543
|
+
<!-- programming language version -->
|
|
544
|
+
<p>
|
|
545
|
+
<cd>
|
|
546
|
+
<cline>
|
|
547
|
+
<!-- hard to tell which is last once sorted, -->
|
|
548
|
+
<!-- so we just mark front *and* end -->
|
|
549
|
+
<xsl:text> | </xsl:text>
|
|
550
|
+
<xsl:for-each select="blocks/block[@order]">
|
|
551
|
+
<xsl:sort select="@order"/>
|
|
552
|
+
<xsl:apply-templates select="." mode="static-horizontal-block"/>
|
|
553
|
+
<xsl:text> | </xsl:text>
|
|
554
|
+
</xsl:for-each>
|
|
555
|
+
</cline>
|
|
556
|
+
</cd>
|
|
557
|
+
</p>
|
|
558
|
+
</statement>
|
|
559
|
+
<!-- We provide a complete solution below, -->
|
|
560
|
+
<!-- so no automatic hint or answer -->
|
|
561
|
+
<xsl:copy-of select="hint"/>
|
|
562
|
+
<xsl:copy-of select="answer"/>
|
|
563
|
+
<!-- Any authored solutions, not derived from problem formulation. -->
|
|
564
|
+
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
565
|
+
<!-- versions on authored ones. -->
|
|
566
|
+
<xsl:copy-of select="solution"/>
|
|
567
|
+
<solution>
|
|
568
|
+
<!-- programming language version -->
|
|
569
|
+
<!-- filter out distractors for the solution -->
|
|
570
|
+
<xsl:variable name="the-blocks" select="blocks/block[not(@correct = 'no')]"/>
|
|
571
|
+
<p>
|
|
572
|
+
<cd>
|
|
573
|
+
<cline>
|
|
574
|
+
<!-- authored in order, but need to follow @ref -->
|
|
575
|
+
<xsl:for-each select="$the-blocks">
|
|
576
|
+
<xsl:apply-templates select="." mode="static-horizontal-block"/>
|
|
577
|
+
<!-- context shift should handle distractors at the end -->
|
|
578
|
+
<xsl:if test="following-sibling::block">
|
|
579
|
+
<xsl:text> </xsl:text>
|
|
580
|
+
</xsl:if>
|
|
581
|
+
</xsl:for-each>
|
|
582
|
+
</cline>
|
|
583
|
+
</cd>
|
|
584
|
+
</p>
|
|
585
|
+
</solution>
|
|
586
|
+
</xsl:template>
|
|
587
|
+
|
|
588
|
+
<xsl:template match="blocks/block" mode="static-horizontal-block">
|
|
589
|
+
<xsl:choose>
|
|
590
|
+
<!-- follow @ref, copy children -->
|
|
591
|
+
<xsl:when test="@ref">
|
|
592
|
+
<xsl:copy-of select="id(@ref)/node()"/>
|
|
593
|
+
</xsl:when>
|
|
594
|
+
<!-- otherwisr duplicate children -->
|
|
595
|
+
<xsl:otherwise>
|
|
596
|
+
<xsl:copy-of select="node()"/>
|
|
597
|
+
</xsl:otherwise>
|
|
598
|
+
</xsl:choose>
|
|
599
|
+
</xsl:template>
|
|
600
|
+
|
|
601
|
+
<!-- Cardsort and Matching Problems -->
|
|
602
|
+
|
|
603
|
+
<!-- Cardsort problems are (roughly) functions, while a (general) -->
|
|
604
|
+
<!-- matching would be a relation. Both match "premise" with -->
|
|
605
|
+
<!-- "response". An implementation might have a colum of "premise" -->
|
|
606
|
+
<!-- to the left and a column of "response" to the right, with an -->
|
|
607
|
+
<!-- interface allowing the reader to make associations. -->
|
|
608
|
+
<!-- The markup for each is similar and different. Some templates -->
|
|
609
|
+
<!-- here do double-duty, some are specific (solutions). -->
|
|
610
|
+
|
|
611
|
+
<!-- Note how this template accomodates both types of problems -->
|
|
612
|
+
<!-- by using match/select and modal template names effectively. -->
|
|
613
|
+
<xsl:template match="*[@exercise-interactive = 'cardsort']|*[@exercise-interactive = 'matching']" mode="runestone-to-static">
|
|
614
|
+
<!-- metadata (idx, title) -->
|
|
615
|
+
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
616
|
+
<!-- Statement -->
|
|
617
|
+
<statement>
|
|
618
|
+
<xsl:copy-of select="statement/node()"/>
|
|
619
|
+
<xsl:apply-templates select="cardsort|matching" mode="cardsort-matching-statement"/>
|
|
620
|
+
</statement>
|
|
621
|
+
<!-- Any authored hint, answers, solutions not derived from -->
|
|
622
|
+
<!-- problem formulation. *Before* automatic solution, so -->
|
|
623
|
+
<!-- numbering matches interactive versions on authored ones. -->
|
|
624
|
+
<xsl:copy-of select="hint"/>
|
|
625
|
+
<xsl:copy-of select="answer"/>
|
|
626
|
+
<xsl:copy-of select="solution"/>
|
|
627
|
+
<!-- Automatically generated solution -->
|
|
628
|
+
<solution>
|
|
629
|
+
<xsl:apply-templates select="cardsort|matching" mode="cardsort-matching-solution"/>
|
|
630
|
+
</solution>
|
|
631
|
+
</xsl:template>
|
|
632
|
+
|
|
633
|
+
<!-- Exercise statement as a tabular -->
|
|
634
|
+
|
|
635
|
+
<!-- For a problem statement, we use a response list re-ordered -->
|
|
636
|
+
<!-- according to response/@order attribute values given by author -->
|
|
637
|
+
<xsl:template match="cardsort|matching" mode="cardsort-matching-statement">
|
|
638
|
+
|
|
639
|
+
<!-- We allow for sorting the premise and response lists, -->
|
|
640
|
+
<!-- independently of each other, so that a static version -->
|
|
641
|
+
<!-- may have a given permutation, decided by the author. -->
|
|
642
|
+
<!-- As a practical matter, a "cardsort" should have an -->
|
|
643
|
+
<!-- ordering, and premise might be easiest. A "matching" -->
|
|
644
|
+
<!-- can be authored in a desired fashion and ordering is -->
|
|
645
|
+
<!-- not needed. -->
|
|
646
|
+
|
|
647
|
+
<!-- Reorder and collect premises -->
|
|
648
|
+
<xsl:variable name="sorted-premises-rtf">
|
|
649
|
+
<xsl:for-each select="match/premise|premise">
|
|
650
|
+
<xsl:sort select="@order"/>
|
|
651
|
+
<xsl:copy-of select="."/>
|
|
652
|
+
</xsl:for-each>
|
|
653
|
+
</xsl:variable>
|
|
654
|
+
<xsl:variable name="sorted-premises" select="exsl:node-set($sorted-premises-rtf)"/>
|
|
655
|
+
|
|
656
|
+
<!-- Reorder and collect responses -->
|
|
657
|
+
<xsl:variable name="sorted-responses-rtf">
|
|
658
|
+
<xsl:for-each select="match/response|response">
|
|
659
|
+
<xsl:sort select="@order"/>
|
|
660
|
+
<xsl:copy-of select="."/>
|
|
661
|
+
</xsl:for-each>
|
|
662
|
+
</xsl:variable>
|
|
663
|
+
<xsl:variable name="sorted-responses" select="exsl:node-set($sorted-responses-rtf)"/>
|
|
664
|
+
|
|
665
|
+
<tabular>
|
|
666
|
+
<xsl:call-template name="matching-row">
|
|
667
|
+
<!-- $sorted-premises gets a root element, collecting the "premise" -->
|
|
668
|
+
<xsl:with-param name="premises" select="$sorted-premises/premise"/>
|
|
669
|
+
<!-- $sorted-responses gets a root element, collecting the "response" -->
|
|
670
|
+
<xsl:with-param name="responses" select="$sorted-responses/response"/>
|
|
671
|
+
</xsl:call-template>
|
|
672
|
+
</tabular>
|
|
673
|
+
</xsl:template>
|
|
674
|
+
|
|
675
|
+
<!-- Make one row of a tabular, recursively. We do not know which list -->
|
|
676
|
+
<!-- is longer (or they are the same length). So we "zip" them together -->
|
|
677
|
+
<!-- by making a row and then effectively discarding the contents of the -->
|
|
678
|
+
<!-- row in the recursive call. (We could pass/increment a row number -->
|
|
679
|
+
<!-- and not keep updating the node-set.) -->
|
|
680
|
+
<xsl:template name="matching-row">
|
|
681
|
+
<xsl:param name="premises"/>
|
|
682
|
+
<xsl:param name="responses"/>
|
|
683
|
+
|
|
684
|
+
<xsl:choose>
|
|
685
|
+
<xsl:when test="not($premises) and not($responses)"/>
|
|
686
|
+
<xsl:otherwise>
|
|
687
|
+
<row>
|
|
688
|
+
<cell>
|
|
689
|
+
<xsl:if test="count($premises) > 1">
|
|
690
|
+
<xsl:attribute name="bottom">
|
|
691
|
+
<xsl:text>minor</xsl:text>
|
|
692
|
+
</xsl:attribute>
|
|
693
|
+
</xsl:if>
|
|
694
|
+
<xsl:copy-of select="$premises[1]/node()"/>
|
|
695
|
+
</cell>
|
|
696
|
+
<!-- An empty (two-character wide) column is a bit of a hack to get -->
|
|
697
|
+
<!-- a visual separation. Could we do better with paragraph cells? -->
|
|
698
|
+
<cell bottom="none"><nbsp/><nbsp/></cell>
|
|
699
|
+
<cell>
|
|
700
|
+
<xsl:if test="count($responses) > 1">
|
|
701
|
+
<xsl:attribute name="bottom">
|
|
702
|
+
<xsl:text>minor</xsl:text>
|
|
703
|
+
</xsl:attribute>
|
|
704
|
+
</xsl:if>
|
|
705
|
+
<xsl:copy-of select="$responses[1]/node()"/>
|
|
706
|
+
</cell>
|
|
707
|
+
</row>
|
|
708
|
+
<xsl:call-template name="matching-row">
|
|
709
|
+
<xsl:with-param name="premises" select="$premises[position() > 1]"/>
|
|
710
|
+
<xsl:with-param name="responses" select="$responses[position() > 1]"/>
|
|
711
|
+
</xsl:call-template>
|
|
712
|
+
</xsl:otherwise>
|
|
713
|
+
</xsl:choose>
|
|
714
|
+
</xsl:template>
|
|
715
|
+
|
|
716
|
+
<!-- Solutions are lists of lists, but seem to -->
|
|
717
|
+
<!-- require two different, but similar, templates. -->
|
|
718
|
+
|
|
719
|
+
<!-- For a solution, we make an unordered list of the responses -->
|
|
720
|
+
<!-- (the "buckets" in true cardsort terminology) and for each -->
|
|
721
|
+
<!-- we make a sub-list wioth the premises that match (the "cards" -->
|
|
722
|
+
<!-- in true cardsort terminology. Note that potential distractors -->
|
|
723
|
+
<!-- are a premise with no response (empty sub-list) and a response -->
|
|
724
|
+
<!-- with no premise (a premise that is null-ish). -->
|
|
725
|
+
<xsl:template match="cardsort" mode="cardsort-matching-solution">
|
|
726
|
+
<p><ul>
|
|
727
|
+
<xsl:for-each select="match">
|
|
728
|
+
<li>
|
|
729
|
+
<p>
|
|
730
|
+
<xsl:choose>
|
|
731
|
+
<xsl:when test="response">
|
|
732
|
+
<xsl:copy-of select="response"/>
|
|
733
|
+
</xsl:when>
|
|
734
|
+
<xsl:otherwise>
|
|
735
|
+
<xsl:text>(</xsl:text>
|
|
736
|
+
<xsl:element name="pi:localize">
|
|
737
|
+
<xsl:attribute name="string-id">uncategorized</xsl:attribute>
|
|
738
|
+
</xsl:element>
|
|
739
|
+
<xsl:text>)</xsl:text>
|
|
740
|
+
</xsl:otherwise>
|
|
741
|
+
</xsl:choose>
|
|
742
|
+
<xsl:if test="premise">
|
|
743
|
+
<ul>
|
|
744
|
+
<xsl:for-each select="premise">
|
|
745
|
+
<li>
|
|
746
|
+
<xsl:copy-of select="."/>
|
|
747
|
+
</li>
|
|
748
|
+
</xsl:for-each>
|
|
749
|
+
</ul>
|
|
750
|
+
</xsl:if>
|
|
751
|
+
</p>
|
|
752
|
+
</li>
|
|
753
|
+
</xsl:for-each>
|
|
754
|
+
</ul></p>
|
|
755
|
+
</xsl:template>
|
|
756
|
+
|
|
757
|
+
<!-- For a solution, we make an unordered list of the -->
|
|
758
|
+
<!-- responses (mirroring the cardsort organization) and -->
|
|
759
|
+
<!-- for each we make a sub-list with the premises that. -->
|
|
760
|
+
<!-- are matched. Distractors are a premise with no -->
|
|
761
|
+
<!-- response (empty sub-list) and a response with no -->
|
|
762
|
+
<!-- premise (a premise that is null-ish). S-->
|
|
763
|
+
<xsl:template match="matching" mode="cardsort-matching-solution">
|
|
764
|
+
<p><ul>
|
|
765
|
+
<xsl:for-each select="response">
|
|
766
|
+
<xsl:variable name="response-xmlid-fenced" select="concat('|', @xml:id, '|')"/>
|
|
767
|
+
<li>
|
|
768
|
+
<p>
|
|
769
|
+
<xsl:copy-of select="."/>
|
|
770
|
+
<!-- form list items of matching premise -->
|
|
771
|
+
<!-- this could be empty, so we not open -->
|
|
772
|
+
<!-- a sub-list prematurely -->
|
|
773
|
+
<xsl:variable name="matched-premises-rtf">
|
|
774
|
+
<!-- context is a "response" step up to get "permise" -->
|
|
775
|
+
<xsl:for-each select="parent::matching/premise">
|
|
776
|
+
<xsl:variable name="the-ref-fenced" select="concat('|', translate(@ref, ' ', '|'), '|')"/>
|
|
777
|
+
<!-- the test for adjacency -->
|
|
778
|
+
<xsl:if test="contains($the-ref-fenced, $response-xmlid-fenced)">
|
|
779
|
+
<li>
|
|
780
|
+
<xsl:copy-of select="."/>
|
|
781
|
+
</li>
|
|
782
|
+
</xsl:if>
|
|
783
|
+
</xsl:for-each>
|
|
784
|
+
</xsl:variable>
|
|
785
|
+
<xsl:variable name="matched-premises" select="exsl:node-set($matched-premises-rtf)"/>
|
|
786
|
+
<!-- create a non-empty sublist of matched premise -->
|
|
787
|
+
<xsl:if test="$matched-premises/li">
|
|
788
|
+
<ul>
|
|
789
|
+
<xsl:copy-of select="$matched-premises"/>
|
|
790
|
+
</ul>
|
|
791
|
+
</xsl:if>
|
|
792
|
+
</p>
|
|
793
|
+
</li>
|
|
794
|
+
</xsl:for-each>
|
|
795
|
+
<!-- And we need to catch premises that do not get -->
|
|
796
|
+
<!-- matched to any response (through null-ish @ref) -->
|
|
797
|
+
<!-- NB: context is now the "matching" -->
|
|
798
|
+
<xsl:variable name="unmatched-premises-rtf">
|
|
799
|
+
<xsl:for-each select="premise">
|
|
800
|
+
<xsl:if test="not(@ref) or (normalize-space(@ref) = '')">
|
|
801
|
+
<li>
|
|
802
|
+
<xsl:copy-of select="."/>
|
|
803
|
+
</li>
|
|
804
|
+
</xsl:if>
|
|
805
|
+
</xsl:for-each>
|
|
806
|
+
</xsl:variable>
|
|
807
|
+
<xsl:variable name="unmatched-premises" select="exsl:node-set($unmatched-premises-rtf)"/>
|
|
808
|
+
<!-- Make a top-level list item "uncategorized" response,-->
|
|
809
|
+
<!-- and populate it with a sub-list of all the premise -->
|
|
810
|
+
<!-- that do not get matched with anything -->
|
|
811
|
+
<xsl:if test="$unmatched-premises/li">
|
|
812
|
+
<li><p>
|
|
813
|
+
<xsl:text>(</xsl:text>
|
|
814
|
+
<xsl:element name="pi:localize">
|
|
815
|
+
<xsl:attribute name="string-id">uncategorized</xsl:attribute>
|
|
816
|
+
</xsl:element>
|
|
817
|
+
<xsl:text>)</xsl:text>
|
|
818
|
+
<ul>
|
|
819
|
+
<xsl:copy-of select="$unmatched-premises/li"/>
|
|
820
|
+
</ul>
|
|
821
|
+
</p></li>
|
|
822
|
+
</xsl:if>
|
|
823
|
+
</ul></p>
|
|
824
|
+
</xsl:template>
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
<!-- Clickable Area -->
|
|
828
|
+
|
|
829
|
+
<xsl:template match="*[@exercise-interactive = 'clickablearea']" mode="runestone-to-static">
|
|
830
|
+
<!-- metadata (idx, title) -->
|
|
831
|
+
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
832
|
+
<!-- Statement -->
|
|
833
|
+
<statement>
|
|
834
|
+
<xsl:copy-of select="statement/node()"/>
|
|
835
|
+
<xsl:apply-templates select="areas" mode="static-areas"/>
|
|
836
|
+
</statement>
|
|
837
|
+
<xsl:copy-of select="hint"/>
|
|
838
|
+
<!-- Any authored answers, not derived from problem formulation. -->
|
|
839
|
+
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
840
|
+
<!-- versions on authored ones. -->
|
|
841
|
+
<xsl:copy-of select="answer"/>
|
|
842
|
+
<answer>
|
|
843
|
+
<p>
|
|
844
|
+
<xsl:element name="pi:localize">
|
|
845
|
+
<xsl:attribute name="string-id">correct</xsl:attribute>
|
|
846
|
+
</xsl:element>
|
|
847
|
+
<xsl:text>: </xsl:text>
|
|
848
|
+
<xsl:for-each select="areas//area[not(@correct = 'no')]">
|
|
849
|
+
<xsl:apply-templates select="." mode="answer-areas"/>
|
|
850
|
+
<xsl:if test="not(position() = last())">
|
|
851
|
+
<xsl:text>; </xsl:text>
|
|
852
|
+
</xsl:if>
|
|
853
|
+
</xsl:for-each>
|
|
854
|
+
<xsl:text>.</xsl:text>
|
|
855
|
+
<xsl:text> </xsl:text>
|
|
856
|
+
<xsl:element name="pi:localize">
|
|
857
|
+
<xsl:attribute name="string-id">incorrect</xsl:attribute>
|
|
858
|
+
</xsl:element>
|
|
859
|
+
<xsl:text>: </xsl:text>
|
|
860
|
+
<xsl:for-each select="areas//area[@correct = 'no']">
|
|
861
|
+
<xsl:apply-templates select="." mode="answer-areas"/>
|
|
862
|
+
<xsl:if test="not(position() = last())">
|
|
863
|
+
<xsl:text>; </xsl:text>
|
|
864
|
+
</xsl:if>
|
|
865
|
+
</xsl:for-each>
|
|
866
|
+
<xsl:text>.</xsl:text>
|
|
867
|
+
</p>
|
|
868
|
+
<xsl:copy-of select="feedback/node()"/>
|
|
869
|
+
</answer>
|
|
870
|
+
<!-- Any authored solutions, not derived from problem formulation. -->
|
|
871
|
+
<!-- *Before* automatic ones, so numbering matches interactive -->
|
|
872
|
+
<!-- versions on authored ones. -->
|
|
873
|
+
<xsl:copy-of select="solution"/>
|
|
874
|
+
<!-- A text version can get markup of correct and incorrect areas -->
|
|
875
|
+
<!-- (italics, strikethrough) but no good way to markup code easily. -->
|
|
876
|
+
<!-- So no "solution" for code versions. -->
|
|
877
|
+
<xsl:if test="not(areas/cline)">
|
|
878
|
+
<solution>
|
|
879
|
+
<xsl:apply-templates select="areas/node()" mode="solution-areas"/>
|
|
880
|
+
</solution>
|
|
881
|
+
</xsl:if>
|
|
882
|
+
</xsl:template>
|
|
883
|
+
|
|
884
|
+
<!-- We do a xerox'ing pass to construct the problem. -->
|
|
885
|
+
<!-- (1) "area" gets dropped (invisible in static) -->
|
|
886
|
+
<!-- [could italicize correct and incorrect?] -->
|
|
887
|
+
<!-- (2) "cline" get reconstructed as a "program" -->
|
|
888
|
+
|
|
889
|
+
<xsl:template match="node()|@*" mode="static-areas">
|
|
890
|
+
<xsl:copy>
|
|
891
|
+
<xsl:apply-templates select="node()|@*" mode="static-areas"/>
|
|
892
|
+
</xsl:copy>
|
|
893
|
+
</xsl:template>
|
|
894
|
+
|
|
895
|
+
<xsl:template match="areas" mode="static-areas">
|
|
896
|
+
<xsl:choose>
|
|
897
|
+
<xsl:when test="cline">
|
|
898
|
+
<!-- code, so make a "program" structure -->
|
|
899
|
+
<program>
|
|
900
|
+
<xsl:attribute name="language">
|
|
901
|
+
<xsl:apply-templates select="." mode="get-programming-language"/>
|
|
902
|
+
</xsl:attribute>
|
|
903
|
+
<input>
|
|
904
|
+
<xsl:apply-templates select="cline" mode="static-areas"/>
|
|
905
|
+
</input>
|
|
906
|
+
</program>
|
|
907
|
+
</xsl:when>
|
|
908
|
+
<xsl:otherwise>
|
|
909
|
+
<!-- regular text, this will match a default template later -->
|
|
910
|
+
<xsl:apply-templates select="*" mode="static-areas"/>
|
|
911
|
+
</xsl:otherwise>
|
|
912
|
+
</xsl:choose>
|
|
913
|
+
</xsl:template>
|
|
914
|
+
|
|
915
|
+
<xsl:template match="areas/cline" mode="static-areas">
|
|
916
|
+
<xsl:apply-templates select="text()|area" mode="static-areas"/>
|
|
917
|
+
<xsl:text>
</xsl:text>
|
|
918
|
+
</xsl:template>
|
|
919
|
+
|
|
920
|
+
<xsl:template match="cline/text()" mode="static-areas">
|
|
921
|
+
<xsl:value-of select="."/>
|
|
922
|
+
</xsl:template>
|
|
923
|
+
|
|
924
|
+
<!-- NB: don't apply to attributes of an "area" (just @correct) -->
|
|
925
|
+
<xsl:template match="area" mode="static-areas">
|
|
926
|
+
<xsl:apply-templates select="node()" mode="static-areas"/>
|
|
927
|
+
</xsl:template>
|
|
928
|
+
|
|
929
|
+
<!-- Modal templates reproduce answers, which could have some -->
|
|
930
|
+
<!-- markup in them? We enter here at each "area" to form the -->
|
|
931
|
+
<!-- lists of correct and incorrect areas. -->
|
|
932
|
+
|
|
933
|
+
<xsl:template match="node()|@*" mode="answer-areas">
|
|
934
|
+
<xsl:copy>
|
|
935
|
+
<xsl:apply-templates select="node()|@*" mode="answer-areas"/>
|
|
936
|
+
</xsl:copy>
|
|
937
|
+
</xsl:template>
|
|
938
|
+
|
|
939
|
+
<xsl:template match="area[parent::cline]" mode="answer-areas">
|
|
940
|
+
<c>
|
|
941
|
+
<!-- NB: don't xerox attributes of an "area" (just @correct) -->
|
|
942
|
+
<xsl:apply-templates select="node()" mode="answer-areas"/>
|
|
943
|
+
</c>
|
|
944
|
+
</xsl:template>
|
|
945
|
+
|
|
946
|
+
<xsl:template match="area[not(parent::cline) and not(@correct = 'no')]" mode="answer-areas">
|
|
947
|
+
<em>
|
|
948
|
+
<!-- NB: don't xerox attributes of an "area" (just @correct) -->
|
|
949
|
+
<xsl:apply-templates select="node()" mode="answer-areas"/>
|
|
950
|
+
</em>
|
|
951
|
+
</xsl:template>
|
|
952
|
+
|
|
953
|
+
<xsl:template match="area[not(parent::cline) and (@correct = 'no')]" mode="answer-areas">
|
|
954
|
+
<delete>
|
|
955
|
+
<!-- NB: don't xerox attributes of an "area" (just @correct) -->
|
|
956
|
+
<xsl:apply-templates select="node()" mode="answer-areas"/>
|
|
957
|
+
</delete>
|
|
958
|
+
</xsl:template>
|
|
959
|
+
|
|
960
|
+
<!-- protect from low-level routines in -common -->
|
|
961
|
+
<xsl:template match="cline/area/text()" mode="answer-areas">
|
|
962
|
+
<xsl:value-of select="."/>
|
|
963
|
+
</xsl:template>
|
|
964
|
+
|
|
965
|
+
<!-- For a text version (only, not a code version) we xerox -->
|
|
966
|
+
<!-- the contents of "areas" and slide-in some highlighting -->
|
|
967
|
+
<!-- of the correct and incorrect "area". -->
|
|
968
|
+
|
|
969
|
+
<xsl:template match="node()|@*" mode="solution-areas">
|
|
970
|
+
<xsl:copy>
|
|
971
|
+
<xsl:apply-templates select="node()|@*" mode="solution-areas"/>
|
|
972
|
+
</xsl:copy>
|
|
973
|
+
</xsl:template>
|
|
974
|
+
|
|
975
|
+
<xsl:template match="area[not(@correct = 'no')]" mode="solution-areas">
|
|
976
|
+
<em>
|
|
977
|
+
<!-- NB: don't xerox attributes of an "area" (just @correct) -->
|
|
978
|
+
<xsl:apply-templates select="node()" mode="solution-areas"/>
|
|
979
|
+
</em>
|
|
980
|
+
</xsl:template>
|
|
981
|
+
|
|
982
|
+
<xsl:template match="area[@correct = 'no']" mode="solution-areas">
|
|
983
|
+
<delete>
|
|
984
|
+
<!-- NB: don't xerox attributes of an "area" (just @correct) -->
|
|
985
|
+
<xsl:apply-templates select="node()" mode="solution-areas"/>
|
|
986
|
+
</delete>
|
|
987
|
+
</xsl:template>
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
<!-- Select -->
|
|
991
|
+
|
|
992
|
+
<xsl:template match="*[@exercise-interactive = 'select']" mode="runestone-to-static">
|
|
993
|
+
<!-- metadata (idx, title) -->
|
|
994
|
+
<xsl:copy-of select="select/preceding-sibling::*"/>
|
|
995
|
+
|
|
996
|
+
<!-- identify the type of "select" -->
|
|
997
|
+
<!-- duplicated in "pretext-runestone.xsl" -->
|
|
998
|
+
<!-- No good place to put this, since static versions -->
|
|
999
|
+
<!-- are forned in assembly phase and we do not want -->
|
|
1000
|
+
<!-- to introduce too many templates there. -->
|
|
1001
|
+
<!-- Save off which type, since context is lost looping over refs -->
|
|
1002
|
+
<xsl:variable name="select-variant">
|
|
1003
|
+
<xsl:choose>
|
|
1004
|
+
<!-- Runestone JS picks a random problem from many-->
|
|
1005
|
+
<xsl:when test="select/@grade='random'">
|
|
1006
|
+
<xsl:text>random</xsl:text>
|
|
1007
|
+
</xsl:when>
|
|
1008
|
+
<!-- Two questions, split across roster into A, B groups. -->
|
|
1009
|
+
<xsl:when test="select/@grade='ab-experiment'">
|
|
1010
|
+
<xsl:text>ab-experiment</xsl:text>
|
|
1011
|
+
</xsl:when>
|
|
1012
|
+
<!-- Two questions (usually), the first will always be graded, -->
|
|
1013
|
+
<!-- while any others may be worked and may be helpful. -->
|
|
1014
|
+
<!-- Colloquially known as a "toggle lock" question. -->
|
|
1015
|
+
<xsl:when test="select/@grade='first'">
|
|
1016
|
+
<xsl:text>first</xsl:text>
|
|
1017
|
+
</xsl:when>
|
|
1018
|
+
<!-- Two questions (usually), any one may be -->
|
|
1019
|
+
<!-- chosen by the reader to be graded. -->
|
|
1020
|
+
<!-- Colloquially known as a "toggle " question. -->
|
|
1021
|
+
<xsl:when test="select/@grade='any'">
|
|
1022
|
+
<xsl:text>any</xsl:text>
|
|
1023
|
+
</xsl:when>
|
|
1024
|
+
<!-- default to "random" selection -->
|
|
1025
|
+
<xsl:otherwise>
|
|
1026
|
+
<xsl:text>random</xsl:text>
|
|
1027
|
+
</xsl:otherwise>
|
|
1028
|
+
</xsl:choose>
|
|
1029
|
+
</xsl:variable>
|
|
1030
|
+
<!-- One simple sentence in a "p", typically presented -->
|
|
1031
|
+
<!-- just after a lead-in title from "exercise" -->
|
|
1032
|
+
<p>
|
|
1033
|
+
<!-- some lead-in explanation -->
|
|
1034
|
+
<xsl:text>Runestone-only: </xsl:text>
|
|
1035
|
+
<xsl:choose>
|
|
1036
|
+
<xsl:when test="$select-variant = 'random'">
|
|
1037
|
+
<xsl:text>exercise to grade will be automatically chosen by Runestone from </xsl:text>
|
|
1038
|
+
</xsl:when>
|
|
1039
|
+
<xsl:when test="$select-variant = 'ab-experiment'">
|
|
1040
|
+
<xsl:text>an A/B experiment (named </xsl:text>
|
|
1041
|
+
<c>
|
|
1042
|
+
<xsl:value-of select="select/@experiment-name"/>
|
|
1043
|
+
</c>
|
|
1044
|
+
<xsl:text>) with </xsl:text>
|
|
1045
|
+
</xsl:when>
|
|
1046
|
+
<xsl:when test="$select-variant = 'first'">
|
|
1047
|
+
<xsl:text>a toggle question where the question graded is </xsl:text>
|
|
1048
|
+
<em>always</em>
|
|
1049
|
+
<xsl:text> the first of </xsl:text>
|
|
1050
|
+
</xsl:when>
|
|
1051
|
+
<xsl:when test="$select-variant = 'any'">
|
|
1052
|
+
<xsl:text>a toggle question where the question graded is </xsl:text>
|
|
1053
|
+
<em>any</em>
|
|
1054
|
+
<xsl:text> question chosen by the reader from </xsl:text>
|
|
1055
|
+
</xsl:when>
|
|
1056
|
+
</xsl:choose>
|
|
1057
|
+
<!-- list "xref" to questions -->
|
|
1058
|
+
<xsl:for-each select="str:tokenize(select/@questions, ' ,')">
|
|
1059
|
+
<!-- cross-reference, will be in default document style -->
|
|
1060
|
+
<xref>
|
|
1061
|
+
<xsl:attribute name="ref">
|
|
1062
|
+
<xsl:value-of select="."/>
|
|
1063
|
+
</xsl:attribute>
|
|
1064
|
+
</xref>
|
|
1065
|
+
<!-- punctuation -->
|
|
1066
|
+
<xsl:choose>
|
|
1067
|
+
<xsl:when test="not($select-variant = 'ab-experiment')">
|
|
1068
|
+
<xsl:choose>
|
|
1069
|
+
<!-- penultimate; trailing comma, plus "or" -->
|
|
1070
|
+
<xsl:when test="count(following-sibling::token) = 1">
|
|
1071
|
+
<xsl:text>, or </xsl:text>
|
|
1072
|
+
</xsl:when>
|
|
1073
|
+
<!-- more, more coming; trailing comma -->
|
|
1074
|
+
<xsl:when test="following-sibling::token">
|
|
1075
|
+
<xsl:text>, </xsl:text>
|
|
1076
|
+
</xsl:when>
|
|
1077
|
+
<!-- done; need final period -->
|
|
1078
|
+
<xsl:otherwise>
|
|
1079
|
+
<xsl:text>.</xsl:text>
|
|
1080
|
+
</xsl:otherwise>
|
|
1081
|
+
</xsl:choose>
|
|
1082
|
+
</xsl:when>
|
|
1083
|
+
<xsl:otherwise>
|
|
1084
|
+
<xsl:choose>
|
|
1085
|
+
<!-- finish "A", and separate from "B" -->
|
|
1086
|
+
<xsl:when test="following-sibling::token">
|
|
1087
|
+
<xsl:text> as (A)</xsl:text>
|
|
1088
|
+
<xsl:text> and </xsl:text>
|
|
1089
|
+
</xsl:when>
|
|
1090
|
+
<!-- final period -->
|
|
1091
|
+
<xsl:otherwise>
|
|
1092
|
+
<xsl:text> as (B).</xsl:text>
|
|
1093
|
+
</xsl:otherwise>
|
|
1094
|
+
</xsl:choose>
|
|
1095
|
+
</xsl:otherwise>
|
|
1096
|
+
</xsl:choose>
|
|
1097
|
+
</xsl:for-each>
|
|
1098
|
+
</p>
|
|
1099
|
+
</xsl:template>
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
<!-- Fill-In the Blanks (Basic) -->
|
|
1103
|
+
|
|
1104
|
+
<xsl:template match="*[@exercise-interactive = 'fillin-basic']" mode="runestone-to-static">
|
|
1105
|
+
<!-- metadata (idx, title) -->
|
|
1106
|
+
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
1107
|
+
<!-- reproduce statement identically, but replace var w/ fillin -->
|
|
1108
|
+
<xsl:apply-templates select="statement" mode="fillin-statement"/>
|
|
1109
|
+
<!-- Any authored hints, answers, solutions, not derived from -->
|
|
1110
|
+
<!-- problem formulation. *Before* automatic ones, so numbering -->
|
|
1111
|
+
<!-- matches interactive versions on authored ones. -->
|
|
1112
|
+
<xsl:copy-of select="hint"/>
|
|
1113
|
+
<xsl:copy-of select="answer"/>
|
|
1114
|
+
<xsl:copy-of select="solution"/>
|
|
1115
|
+
<xsl:apply-templates select="statement" mode="fillin-solution"/>
|
|
1116
|
+
</xsl:template>
|
|
1117
|
+
|
|
1118
|
+
<!-- Fillin Statement -->
|
|
1119
|
+
<xsl:template match="node()|@*" mode="fillin-statement">
|
|
1120
|
+
<xsl:copy>
|
|
1121
|
+
<xsl:apply-templates select="node()|@*" mode="fillin-statement"/>
|
|
1122
|
+
</xsl:copy>
|
|
1123
|
+
</xsl:template>
|
|
1124
|
+
|
|
1125
|
+
<xsl:template match="var" mode="fillin-statement">
|
|
1126
|
+
<fillin>
|
|
1127
|
+
<xsl:attribute name="characters">
|
|
1128
|
+
<xsl:choose>
|
|
1129
|
+
<xsl:when test="@width">
|
|
1130
|
+
<xsl:value-of select="@width"/>
|
|
1131
|
+
</xsl:when>
|
|
1132
|
+
<xsl:otherwise>
|
|
1133
|
+
<!-- arbitrary default width -->
|
|
1134
|
+
<xsl:text>5</xsl:text>
|
|
1135
|
+
</xsl:otherwise>
|
|
1136
|
+
</xsl:choose>
|
|
1137
|
+
</xsl:attribute>
|
|
1138
|
+
</fillin>
|
|
1139
|
+
</xsl:template>
|
|
1140
|
+
|
|
1141
|
+
<!-- Fillin complete solution -->
|
|
1142
|
+
|
|
1143
|
+
<xsl:template match="node()|@*" mode="fillin-solution">
|
|
1144
|
+
<xsl:copy>
|
|
1145
|
+
<xsl:apply-templates select="node()|@*" mode="fillin-solution"/>
|
|
1146
|
+
</xsl:copy>
|
|
1147
|
+
</xsl:template>
|
|
1148
|
+
|
|
1149
|
+
<!-- Don't duplicate xml:id. Nobody should point into the solution. -->
|
|
1150
|
+
<!-- Note that any internal link references will point to the original not the copy -->
|
|
1151
|
+
<xsl:template match="@xml:id" mode="fillin-solution"/>
|
|
1152
|
+
|
|
1153
|
+
<!-- Append to a label -->
|
|
1154
|
+
<xsl:template match="@label" mode="fillin-solution">
|
|
1155
|
+
<xsl:attribute name="label">
|
|
1156
|
+
<xsl:value-of select="."/>
|
|
1157
|
+
<xsl:text>-fitb-solution</xsl:text>
|
|
1158
|
+
</xsl:attribute>
|
|
1159
|
+
</xsl:template>
|
|
1160
|
+
|
|
1161
|
+
<xsl:template match="statement" mode="fillin-solution">
|
|
1162
|
+
<xsl:variable name="exercise" select=".."/>
|
|
1163
|
+
<solution>
|
|
1164
|
+
<xsl:apply-templates select="node()|@*" mode="fillin-solution"/>
|
|
1165
|
+
<!-- xerox feedback for correct response on each var -->
|
|
1166
|
+
<xsl:for-each select="../setup/var/condition[1]/feedback">
|
|
1167
|
+
<xsl:apply-templates select="node()" mode="fillin-solution"/>
|
|
1168
|
+
</xsl:for-each>
|
|
1169
|
+
<xsl:for-each select=".//fillin[@answer]">
|
|
1170
|
+
<xsl:variable name="fillin-name" select="@name"/>
|
|
1171
|
+
<xsl:variable name="fillin-pos" select="position()"/>
|
|
1172
|
+
<xsl:choose>
|
|
1173
|
+
<!-- If #evaluate matches by name, find feedback on a correct result -->
|
|
1174
|
+
<xsl:when test="$exercise/evaluation/evaluate[@name='$fillin-name']/test[@correct='yes']">
|
|
1175
|
+
<xsl:apply-templates select="$exercise/evaluation/evaluate[@name='$fillin-name']/test[@correct='yes']/feedback/node()" mode="fillin-solution"/>
|
|
1176
|
+
</xsl:when>
|
|
1177
|
+
<!-- Otherwise #evaluate matches by order, find feedback on a correct result -->
|
|
1178
|
+
<xsl:when test="$exercise/evaluation/evaluate[$fillin-pos]/test[@correct='yes']">
|
|
1179
|
+
<xsl:apply-templates select="$exercise/evaluation/evaluate[$fillin-pos]/test[@correct='yes']/feedback/node()" mode="fillin-solution"/>
|
|
1180
|
+
</xsl:when>
|
|
1181
|
+
</xsl:choose>
|
|
1182
|
+
</xsl:for-each>
|
|
1183
|
+
<xsl:if test="../evaluation[@answers-coupled='yes']">
|
|
1184
|
+
<xsl:apply-templates select="$exercise/evaluation/evaluate[@all='yes']/test[@correct='yes']/feedback/node()" mode="fillin-solution"/>
|
|
1185
|
+
</xsl:if>
|
|
1186
|
+
</solution>
|
|
1187
|
+
</xsl:template>
|
|
1188
|
+
|
|
1189
|
+
<xsl:template match="var" mode="fillin-solution">
|
|
1190
|
+
<!-- NB: this code is used in formulating HTML representations -->
|
|
1191
|
+
<!-- count location of (context) "var" in problem statement -->
|
|
1192
|
+
<xsl:variable name="location">
|
|
1193
|
+
<xsl:number from="statement"/>
|
|
1194
|
+
</xsl:variable>
|
|
1195
|
+
<!-- locate corresponding "var" in "setup" -->
|
|
1196
|
+
<xsl:variable name="setup-var" select="ancestor::exercise/setup/var[position() = $location]"/>
|
|
1197
|
+
|
|
1198
|
+
<!-- Know can tell what the correct answer is, from first "condition"-->
|
|
1199
|
+
<fillin characters="1"/>
|
|
1200
|
+
<xsl:choose>
|
|
1201
|
+
<xsl:when test="$setup-var/condition[1]/@number">
|
|
1202
|
+
<m>
|
|
1203
|
+
<xsl:value-of select="$setup-var/condition[1]/@number"/>
|
|
1204
|
+
</m>
|
|
1205
|
+
</xsl:when>
|
|
1206
|
+
<xsl:when test="$setup-var/condition[1]/@string">
|
|
1207
|
+
<xsl:value-of select="$setup-var/condition[1]/@string"/>
|
|
1208
|
+
</xsl:when>
|
|
1209
|
+
</xsl:choose>
|
|
1210
|
+
<fillin characters="1"/>
|
|
1211
|
+
</xsl:template>
|
|
1212
|
+
|
|
1213
|
+
<!-- Fill-In the Blanks (Complete) -->
|
|
1214
|
+
|
|
1215
|
+
<xsl:template match="*[@exercise-interactive = 'fillin']" mode="runestone-to-static">
|
|
1216
|
+
<!-- metadata (idx, title) -->
|
|
1217
|
+
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
1218
|
+
<!-- reproduce statement identically, but replace var w/ fillin -->
|
|
1219
|
+
<xsl:apply-templates select="statement" mode="fillin-statement"/>
|
|
1220
|
+
<!-- Any authored hints, answers, solutions, not derived from -->
|
|
1221
|
+
<!-- problem formulation. *Before* automatic ones, so numbering -->
|
|
1222
|
+
<!-- matches interactive versions on authored ones. -->
|
|
1223
|
+
<xsl:copy-of select="hint"/>
|
|
1224
|
+
<xsl:copy-of select="answer"/>
|
|
1225
|
+
<xsl:choose>
|
|
1226
|
+
<xsl:when test="solution[@include-automatic='no']">
|
|
1227
|
+
<xsl:copy-of select="solution"/>
|
|
1228
|
+
</xsl:when>
|
|
1229
|
+
<xsl:otherwise>
|
|
1230
|
+
<xsl:apply-templates select="statement" mode="fillin-solution"/>
|
|
1231
|
+
<xsl:copy-of select="solution"/>
|
|
1232
|
+
</xsl:otherwise>
|
|
1233
|
+
</xsl:choose>
|
|
1234
|
+
</xsl:template>
|
|
1235
|
+
|
|
1236
|
+
<!-- Fillin Statement -->
|
|
1237
|
+
<xsl:template match="fillin" mode="fillin-statement">
|
|
1238
|
+
<fillin>
|
|
1239
|
+
<xsl:attribute name="characters">
|
|
1240
|
+
<xsl:choose>
|
|
1241
|
+
<xsl:when test="@width">
|
|
1242
|
+
<xsl:value-of select="@width"/>
|
|
1243
|
+
</xsl:when>
|
|
1244
|
+
<xsl:otherwise>
|
|
1245
|
+
<!-- arbitrary default width -->
|
|
1246
|
+
<xsl:text>5</xsl:text>
|
|
1247
|
+
</xsl:otherwise>
|
|
1248
|
+
</xsl:choose>
|
|
1249
|
+
</xsl:attribute>
|
|
1250
|
+
</fillin>
|
|
1251
|
+
</xsl:template>
|
|
1252
|
+
|
|
1253
|
+
<!-- Fillin complete solution -->
|
|
1254
|
+
<xsl:template match="fillin" mode="fillin-solution">
|
|
1255
|
+
<!-- Correct answer is in @answer. -->
|
|
1256
|
+
<fillin characters="1"/>
|
|
1257
|
+
<xsl:choose>
|
|
1258
|
+
<xsl:when test="@mode='math' or @mode='number'">
|
|
1259
|
+
<m><xsl:value-of select="@answer"/></m>
|
|
1260
|
+
</xsl:when>
|
|
1261
|
+
<xsl:otherwise>
|
|
1262
|
+
<xsl:value-of select="@answer"/>
|
|
1263
|
+
</xsl:otherwise>
|
|
1264
|
+
</xsl:choose>
|
|
1265
|
+
<fillin characters="1"/>
|
|
1266
|
+
</xsl:template>
|
|
1267
|
+
|
|
1268
|
+
<!-- Short Answer -->
|
|
1269
|
+
|
|
1270
|
+
<!-- Authored with a "response" element, we effectively drop it here -->
|
|
1271
|
+
<xsl:template match="*[@exercise-interactive = 'shortanswer']" mode="runestone-to-static">
|
|
1272
|
+
<!-- metadata (idx, title) -->
|
|
1273
|
+
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
1274
|
+
<!-- reproduce usual components -->
|
|
1275
|
+
<xsl:copy-of select="statement"/>
|
|
1276
|
+
<!-- skip over response until it carries something relevant -->
|
|
1277
|
+
<xsl:copy-of select="hint"/>
|
|
1278
|
+
<xsl:copy-of select="answer"/>
|
|
1279
|
+
<xsl:copy-of select="solution"/>
|
|
1280
|
+
</xsl:template>
|
|
1281
|
+
|
|
1282
|
+
<!-- Queries -->
|
|
1283
|
+
|
|
1284
|
+
<xsl:template match="query" mode="runestone-to-static">
|
|
1285
|
+
<paragraphs>
|
|
1286
|
+
<!-- no period, it is supplied by conversions -->
|
|
1287
|
+
<title>
|
|
1288
|
+
<xsl:element name="pi:localize">
|
|
1289
|
+
<xsl:attribute name="string-id">query</xsl:attribute>
|
|
1290
|
+
</xsl:element>
|
|
1291
|
+
</title>
|
|
1292
|
+
<!-- reproduce structured statement's pieces -->
|
|
1293
|
+
<xsl:copy-of select="statement/*"/>
|
|
1294
|
+
<xsl:choose>
|
|
1295
|
+
<xsl:when test="choices">
|
|
1296
|
+
<p><ol format="1.">
|
|
1297
|
+
<xsl:for-each select="choices/choice">
|
|
1298
|
+
<li>
|
|
1299
|
+
<xsl:copy-of select="."/>
|
|
1300
|
+
</li>
|
|
1301
|
+
</xsl:for-each>
|
|
1302
|
+
</ol></p>
|
|
1303
|
+
</xsl:when>
|
|
1304
|
+
<xsl:when test="@scale">
|
|
1305
|
+
<!-- A pre-formatted "display" of the integer choices, -->
|
|
1306
|
+
<!-- which could be printed and circled by the reader. -->
|
|
1307
|
+
<pre>
|
|
1308
|
+
<xsl:apply-templates select="." mode="scale-choices"/>
|
|
1309
|
+
</pre>
|
|
1310
|
+
</xsl:when>
|
|
1311
|
+
<xsl:otherwise/>
|
|
1312
|
+
</xsl:choose>
|
|
1313
|
+
</paragraphs>
|
|
1314
|
+
</xsl:template>
|
|
1315
|
+
|
|
1316
|
+
<!-- Recursively count-up and layout choices with rows of -->
|
|
1317
|
+
<!-- 10 choices each, with blank lines between the rows. -->
|
|
1318
|
+
<xsl:template match="query" mode="scale-choices">
|
|
1319
|
+
<xsl:param name="the-choice" select="'1'"/>
|
|
1320
|
+
|
|
1321
|
+
<xsl:choose>
|
|
1322
|
+
<!-- Done. Emit and that's it -->
|
|
1323
|
+
<xsl:when test="$the-choice = ./@scale">
|
|
1324
|
+
<xsl:value-of select="$the-choice"/>
|
|
1325
|
+
</xsl:when>
|
|
1326
|
+
<!-- Done with a row, but not done. Newline, and blankline. -->
|
|
1327
|
+
<xsl:when test="$the-choice mod 10 = 0">
|
|
1328
|
+
<xsl:value-of select="$the-choice"/>
|
|
1329
|
+
<xsl:text>

</xsl:text>
|
|
1330
|
+
<xsl:apply-templates select="." mode="scale-choices">
|
|
1331
|
+
<xsl:with-param name="the-choice" select="$the-choice + 1"/>
|
|
1332
|
+
</xsl:apply-templates>
|
|
1333
|
+
</xsl:when>
|
|
1334
|
+
<!-- Mid-row, use two spaces to separate. -->
|
|
1335
|
+
<xsl:otherwise>
|
|
1336
|
+
<xsl:value-of select="$the-choice"/>
|
|
1337
|
+
<xsl:text>  </xsl:text>
|
|
1338
|
+
<xsl:apply-templates select="." mode="scale-choices">
|
|
1339
|
+
<xsl:with-param name="the-choice" select="$the-choice + 1"/>
|
|
1340
|
+
</xsl:apply-templates>
|
|
1341
|
+
</xsl:otherwise>
|
|
1342
|
+
</xsl:choose>
|
|
1343
|
+
</xsl:template>
|
|
1344
|
+
|
|
1345
|
+
|
|
1346
|
+
<!-- Active Code -->
|
|
1347
|
+
|
|
1348
|
+
<xsl:template match="*[@exercise-interactive = 'coding']" mode="runestone-to-static">
|
|
1349
|
+
<!-- metadata (idx, title) -->
|
|
1350
|
+
<xsl:copy-of select="statement/preceding-sibling::*"/>
|
|
1351
|
+
<statement>
|
|
1352
|
+
<!-- duplicate the authored prompt/statement -->
|
|
1353
|
+
<xsl:copy-of select="statement/node()"/>
|
|
1354
|
+
<!-- Bring up the program as part of the problem statement and -->
|
|
1355
|
+
<!-- also neuter any @interactive indication. This was not -->
|
|
1356
|
+
<!-- tagged as a coding exercise without a "program" outside -->
|
|
1357
|
+
<!-- the "statement", but we are careful about not making an -->
|
|
1358
|
+
<!-- empty "program" where there is none. -->
|
|
1359
|
+
<xsl:if test="program">
|
|
1360
|
+
<xsl:element name="program">
|
|
1361
|
+
<xsl:copy-of select="program/@*[not(name() = 'interactive')]"/>
|
|
1362
|
+
<xsl:copy-of select="program/node()"/>
|
|
1363
|
+
</xsl:element>
|
|
1364
|
+
</xsl:if>
|
|
1365
|
+
</statement>
|
|
1366
|
+
<xsl:copy-of select="hint"/>
|
|
1367
|
+
<xsl:copy-of select="answer"/>
|
|
1368
|
+
<xsl:copy-of select="solution"/>
|
|
1369
|
+
</xsl:template>
|
|
1370
|
+
|
|
1371
|
+
|
|
1372
|
+
<xsl:template match="datafile" mode="runestone-to-static">
|
|
1373
|
+
<!-- Some templates and variables are defined in -common for consistency -->
|
|
1374
|
+
|
|
1375
|
+
<!-- Mostly the data file is a "pre", or an "image", but we -->
|
|
1376
|
+
<!-- want to have a title of sorts indicating the filename. -->
|
|
1377
|
+
<!-- To accomplish an overall element that won't disrupt -->
|
|
1378
|
+
<!-- subsequent automatic ids, we do a bit of a hack: a -->
|
|
1379
|
+
<!-- "sidebyside" as the overall element with a "stack". -->
|
|
1380
|
+
<sidebyside>
|
|
1381
|
+
<stack>
|
|
1382
|
+
<!-- faux title -->
|
|
1383
|
+
<p>
|
|
1384
|
+
<xsl:element name="pi:localize">
|
|
1385
|
+
<xsl:attribute name="string-id">data</xsl:attribute>
|
|
1386
|
+
</xsl:element>
|
|
1387
|
+
<xsl:text>: </xsl:text>
|
|
1388
|
+
<c>
|
|
1389
|
+
<xsl:value-of select="@filename"/>
|
|
1390
|
+
</c>
|
|
1391
|
+
</p>
|
|
1392
|
+
<!-- image or code, one panel -->
|
|
1393
|
+
<xsl:choose>
|
|
1394
|
+
<xsl:when test="image">
|
|
1395
|
+
<xsl:copy-of select="image"/>
|
|
1396
|
+
</xsl:when>
|
|
1397
|
+
<xsl:when test="pre">
|
|
1398
|
+
<!-- provide default rows and cols, sync with dynamic version -->
|
|
1399
|
+
<xsl:variable name="desired-rows">
|
|
1400
|
+
<xsl:choose>
|
|
1401
|
+
<xsl:when test="@rows">
|
|
1402
|
+
<xsl:value-of select="@rows"/>
|
|
1403
|
+
</xsl:when>
|
|
1404
|
+
<xsl:otherwise>
|
|
1405
|
+
<xsl:value-of select="$datafile-default-rows"/>
|
|
1406
|
+
</xsl:otherwise>
|
|
1407
|
+
</xsl:choose>
|
|
1408
|
+
</xsl:variable>
|
|
1409
|
+
<xsl:variable name="desired-cols">
|
|
1410
|
+
<xsl:choose>
|
|
1411
|
+
<xsl:when test="@cols">
|
|
1412
|
+
<xsl:value-of select="@cols"/>
|
|
1413
|
+
</xsl:when>
|
|
1414
|
+
<xsl:otherwise>
|
|
1415
|
+
<xsl:value-of select="$datafile-default-cols"/>
|
|
1416
|
+
</xsl:otherwise>
|
|
1417
|
+
</xsl:choose>
|
|
1418
|
+
</xsl:variable>
|
|
1419
|
+
<pre>
|
|
1420
|
+
<!-- form an "upper-left-corner" view -->
|
|
1421
|
+
<xsl:call-template name="text-viewport">
|
|
1422
|
+
<xsl:with-param name="nrows" select="$desired-rows"/>
|
|
1423
|
+
<xsl:with-param name="ncols" select="$desired-cols"/>
|
|
1424
|
+
<xsl:with-param name="text">
|
|
1425
|
+
<!-- defined in -common -->
|
|
1426
|
+
<xsl:apply-templates select="." mode="datafile-text-contents"/>
|
|
1427
|
+
</xsl:with-param>
|
|
1428
|
+
</xsl:call-template>
|
|
1429
|
+
</pre>
|
|
1430
|
+
</xsl:when>
|
|
1431
|
+
<!-- no other source/PTX element is supported , bail out-->
|
|
1432
|
+
<xsl:otherwise/>
|
|
1433
|
+
</xsl:choose>
|
|
1434
|
+
</stack>
|
|
1435
|
+
</sidebyside>
|
|
1436
|
+
</xsl:template>
|
|
1437
|
+
|
|
1438
|
+
</xsl:stylesheet>
|