summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/exam-n/exam-n.dtx
blob: ce752727b85774d2c9881332db2c6a83aad70b83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
% \iffalse
% This is exam-n.dtx, which supports formatting exam papers.
%
% Generated file : DO NOT EDIT
%
%% Release version exam-n-1.4.0, 2022 October 10.
%% See https://purl.org/nxg/dist/exam-n
%% and https://heptapod.host/nxg/exam-n
%% and https://www.ctan.org/pkg/exam-n
%%
%%%% File: exam-n.dtx
%%%% Copyright 2005--2022, Norman Gray
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
%% of this license or (at your option) any later version.
%% The latest version of this license is in
%%   http://www.latex-project.org/lppl.txt
%% and version 1.3 or later is part of all distributions of LaTeX
%% version 2005/12/01 or later.
%%
%% This work has the LPPL maintenance status `maintained'.
%%
%% The Current Maintainer of this work is Norman Gray <https://nxg.me.uk>
%%
%% This work consists of the files exam-n.dtx and exam-n.ins,
%% the derived file exam-n.cls,
%% and the associated *.clo files.


%<+package|driver|example>%%%% Source: a91e9cff7cac, 2022-10-10T13:33:17+01:00
%%
%<*package|driver>

%</package|driver>
%<+package>\NeedsTeXFormat{LaTeX2e}
%<+package>\ProvidesClass{exam-n}[2022/10/10 exam-n-1.4.0]
%<+package>\typeout{Class: `exam-n-1.4.0 <2022/10/10>}
%
%<*driver>
\documentclass{ltxdoc}
\title{exam-n: exam papers}
\author{Norman Gray\\(\texttt{norman.gray@glasgow.ac.uk})}
\date{Version exam-n-1.4.0, 2022 October 10}% ...rather than exam-n-1.4.0, which isn't reader-focused
\usepackage{url}
\newcommand\Lopt[1]{\textsf {#1}} % options
\newcommand\file[1]{\texttt {#1}}
\newcommand\Lcount[1]{\textsl {\small#1}}
\newcommand\Lenv[1]{\texttt{\{#1\}}} %environments
\newcommand\Lpackage[1]{[\textsf{#1}]} %packages
%Make command strings easier to write, with \cmd|\foo|
%{\catcode`\<=\active \gdef<#1>{\meta{#1}}}
{\catcode`\<=\active
  \gdef<#1>{{\ensuremath\langle\normalfont\textsl{#1}\ensuremath\rangle}}}
\def\cmd{\begingroup
 \catcode`\\=12 \catcode`\{=12 \catcode`\}=12 \catcode`\#=12
 \catcode`\<=\active \catcode`\|=12
 \docmd}
\def\docmd|#1|{\texttt{#1}\endgroup}

\def\secref#1{Sect.~\ref{#1}}

% Various definitions of this package, so we can document them.
\usepackage{examndefs}

% Uncomment \OnlyDescription to skip the implementation
%\OnlyDescription
\begin{document}
\maketitle
\tableofcontents
\bigskip
\DocInput{exam-n.dtx}
\end{document}
%</driver>
%
% \fi
%
% \noindent This class file supports creating exam papers.
% This is intended as part of a slightly larger system for assembling
% and managing the papers, by combining questions from multiple authors.
%
% This document is addressed to the exams convener, or someone
% responsible for the overall exam; it goes into complete detail about
% the class file, and how to customise it.  There is more compact
% documentation for the class, addressed to the authors of individual
% questions, in the companion document `Notes for Authors'.
%
% The most up-to-date version of this class can be found at
% \url{http://purl.org/nxg/dist/exam-n}.
%
% \newpage
%
% \section{Description}
%
% Usage:
% \begin{verbatim}
%    \documentclass[options...]{exam-n}
%    <preamble declarations>
%    \begin{document}
%    \maketitle
%    \begin{question}...\end{question}
%    ...
%    \end{document}
% \end{verbatim}
%
% \subsection{Class options}
% \label{s:options}
%
% The class takes the following options.  Note that these options are
% processed in order, so if an option changes a default
% (for example, \Lopt{draft} sets \Lopt{showsolutions} by default),
% then it can be overridden by an option later in the list.
% \begin{description}
%    \item[\Lopt{compose}, \Lopt{draft}, \Lopt{final}]
%    When composing questions, you should give
%    the \Lopt{compose} option to \Lenv{exam-n}; when assembling the paper, you
%    should use \Lopt{draft}; and you should use \Lopt{final} only for
%    the final version.
%    The \Lopt{draft} option switches on the \Lopt{showsolutions}
%    option (below), displays |\comment| remarks,
%    and makes some mild layout changes.
%    The \Lopt{compose} option implies the \Lopt{showsolutions} option,
%    causes questions to be formatted one per page, and turns off
%    various checks on the number of questions; the \Lopt{draft} option
%    should have the same pagination as the final paper and shifts the
%    body of the paper to the left so that marginal comments are
%    easier to write and read; the \Lopt{final} option turns off the
%    |\comment| command.
%
%    \item[\Lopt{cmfonts}, \Lopt{psfonts}, \Lopt{mathptm},
%      \Lopt{mathtime}, \Lopt{mtpro2}, \Lopt{stix2}]
%    The \Lopt{cmfonts} option (the default) uses the Computer Modern fonts for the
%    document, and the other options use PostScript or OpenType fonts.
%
%    The \Lopt{mathtime} or \Lopt{mtpro2} options select PostScript
%    Times Roman, Helvetica and Courier for the body text, plus either Mathtime or
%    Mathtime Professional~2 to typeset maths (this is commercially
%    distributed by
%    PC\TeX\footnote{\url{https://www.pctex.com/mtpro2.html}}, and
%    designed to be compatible with Times Roman).  A broadly
%    compatible alternative to this is to use the \Lopt{mathptm}
%    option, but although this is free, the results aren't impressive.
%
%    A final option is to use the \Lopt{stix2} option to choose
%    specifically and exclusively the
%    (free) STIX2 font set\footnote{\url{https://www.stixfonts.org}}
%    for both text and maths.
%    On this site, you will need to download and install
%    the files in the \url{static_otf.zip} bundle.
%    Note that the support for this option is somewhat experimental, and
%    at present, this package simply uses (serif) STIX2 roman
%    for all font shapes.  Since the exam style doesn't use any sans serif by
%    default, this doesn't matter, at some level.  The
%    \Lopt{sansserif} option is not compatible with this option (the option
%    won't produce any error, but neither will it produce any effect).
%
% \textbf{FIXME: remove this when unicode-math is working.}
%    \textbf{Note:} because of an unfortunate interaction between packages, the
%    \Lpackage{stix2} and \Lpackage{siunitx} packages can produce unexpected
%    results with some combinations of \TeX\ engine and package version
%    (specifically, \Lpackage{stix2} plus \Lpackage{siunitx}
%    and \cmd|\micro| or \cmd|\circ| can produce garbled characters
%    without \LaTeX\ reporting an error).  Before \TeX Live 2021, this
%    worked correctly with Xe\LaTeX\ and Lua\LaTeX, but not with
%    pdf\LaTeX; from \TeX Live 2021 this works as expected with
%    pdf\LaTeX, but works with the other two \emph{only} if you load
%    the \Lpackage{siunitx} package with
%    \cmd|\usepackage{siunitx}[=v2]|.  I hope that future versions of
%    one or other of these packages will make clear how this package
%    should handle them, in a way which avoids this special-casing.
%    \iffalse See
%      https://github.com/josephwright/siunitx/issues/550
%      https://github.com/josephwright/siunitx/issues/547
%      https://github.com/stipub/stixfonts/issues/235
%    \fi
%
%    The handling of non-standard fonts has always been slightly
%    fragile in \LaTeX.
%    The \Lopt{mtpro2} and \Lopt{stix2} options are those currently
%    most used by the author, and are therefore the ones most likely
%    to get the various font nuances correct.
%
%    \item[\Lopt{uprightpi}]By default $\pi$ is set slanted, as is the
%    usual \LaTeX\ default.  When this is referring to the circular
%    constant, however, this should (in some typesetting styles) be set as an upright letter, in
%    fonts which support this.  If the option \Lopt{uprightpi} is
%    present, then |\pi| is defined to produce an upright letter, and
%    the command |\italicpi| is defined to produce the slanted version.
%    Whether this option is supplied or not, the macro |\uppi| will
%    produce a single upright~$\pi$.
%    Note: this is at present implemented
%    only for the \Lopt{mtpro2} and \Lopt{stix2} options,
%    and the combination of pdflatex+stix2 does not support |\uppi| at present.
%
%    \item[\Lopt{(no)siunitx}] Load the \Lpackage{siunitx} package, or
%    not.  The default is yes.  The |\units| macro, described below,
%    still exists as an alternative, but will be removed in a
%    forthcoming release (probably after 1.4.x).
%
%    \item[\Lopt{(no)showsolutions}]
%    These control whether the solutions to
%    the questions are shown on the paper or not.  \Lopt{showsolutions} is the
%    default when the either \Lopt{draft} or \Lopt{compose} options is
%    present, and \Lopt{noshowsolutions} in \Lopt{final} case,
%    though this will be overridden by one of the
%    \Lopt{\{no\}showsolutions} options later in the list.
%
%    \item[\Lopt{(no)perquestionmarks} and \Lopt{(no)showmarktotals}]
%    These control whether mark totals and subtotals are tracked within
%    the question (perquestionmarks), and whether the total available
%    marks are displayed at the end of the question (showmarktotals).
%    See \secref{s:question} for more discussion (this
%    option was called \Lopt{showmarks} up to release 0.15).
%
%    \item[\Lopt{(no)pageperquestion}]
%    If the option \Lopt{pageperquestion} is present, then each
%    question is on a separate page.  Option \Lopt{nopageperquestion}
%    is the default.  This is most often set by default by one of the
%    other options, or by a \file{.clo} file.
%
%    \item[\Lopt{oneside}, \Lopt{twoside}]
%    These control whether the document is formatted for
%    one- or twosided printing.  This is a standard option, which is
%    redundant in this case, since in this document style there is no
%    difference in formatting.  You may in principle use other
%    {article} options, though you are encouraged not to.
%
%    \item[\Lopt{fleqn}]
%    Display equations flush-left, rather than centred.  You generally
%    won't set this in the |\documentclass| options -- it's here so
%    that it can be set in a |.clo| file.
%
%    \item[\Lopt{sloppydescription}]
%    Disables the requirement that all exam metadata be present.  See
%    the discussion of |\universitycoursecode| below.
%
%    \item[\Lopt{mono}, \Lopt{colour}]
%    The university logo is typeset in colour by default, as is the
%    solution text; the \Lopt{mono} option causes everything to be in
%    mono instead.  The \Lopt{colour} option does nothing, but is
%    present for symmetry.
%
%    \item[\Lopt{sansserif}]
%    Use a sans serif font for the body text.  This is plug-ugly, not
%    least because it doesn't match the maths font; also, it may be
%    easier or harder for dyslexic students to read (there seems to be
%    a variety of advice here, in both directions, ranging from
%    confident to dogmatic, but remarkably little solid evidence
%    either way).
%
%    \item[\Lopt{largefont}, or \Lopt{hugefont}]
%    Produce a version of the paper in a `big' font (18pt) or `huge' font (36pt) for
%    the benefit of students with visual impairments.  See notes below.
%
% \end{description}
%
% Any other options are interpreted as an instruction to read in a
% \file{.clo} file, containing course-, department- or group-specific style
% modifications.  Most typically, these changes will affect the
% rubric, and the sheet of physical constants.
% The only generic style option is \Lopt{myclass}
% (which is included as an example of how such a file is written).
% See \secref{s:custom} below.
%
% In some circumstances -- for example when processing exam scripts
% under the control of a Makefile or script -- it can be convenient to
% control package options from outside the package.  If there is a
% file called \texttt{exam-n.config} in the input path (most likely in
% the same directory as the exam paper), then this is read in when any
% exam script is processed, and will supplement any
% options in the |\documentclass| line.  For example, if this file were present
% and contained the line |\ExecuteOptions{showsolutions}|, then the
% typeset exam would include the solutions.  Note that this will
% supplement, \emph{but not override}, options in the input file's |\documentclass|;
% it is therefore useful only for switching options away from the default.
%
% The exam-n class includes the \Lpackage{amsmath} package, so you can
% make immediate use of amsmath features if you wish (see
% \texttt{\small http://www.ams.org/tex/amslatex.html} for discussion).
%
% The change of font size with the \Lopt{hugefont} option requires a
% couple of minor layout changes.  You may need to force some similar
% changes in the exam paper, in this case.  You can do that by bracketing the
% adjusted text in \cmd|\ifbigfont<big font material>\else<normal font
% material>\fi|; the |\ifbigfont| flag is true in the case of
% \Lopt{hugefont}, but not \Lopt{largefont}.  If you want the
% |\ifbigfont| flag to apply to \Lopt{largefont}, too, then you may
% set |\bigfonttrue| in a suitable place.  The \Lpackage{amsmath}
% \texttt{multline} environment can be useful here.  The exams
% convener should review the result carefully: a few judicious
% \cmd|\ifbigfont\newpage\fi| insertions can make the result look less
% awful.  The \Lopt{largefont} and \Lopt{hugefont} options apply to
% the content of solutions if the \Lopt{showsolutions} option is
% present; this may or may not be the optimal choice.
%
% At the bottom of each page, you see a faint identification code, such
% as `QM/123-456'.  This consists of an exam identifier, extracted from
% the exam preamble, plus a code which changes each time \LaTeX\ is
% run. This helps you avoid collation accidents, and to distinguish
% between slightly different versions of the printed document.
% The identifier is based on the date and time, so changes each time
% you run \LaTeX\ on the file (that is, it identifies a printing,
% rather than a source-file version).
%
% \subsection{The Question environment}
% \label{s:question}
%
% Within the document, you include questions within a \Lenv{question}
% environment, within which you may further have
% \Lenv{questiondata} and \Lenv{solution} environments.
%
% \DescribeEnv{question}
% The \Lenv{question} environment delimits a single exam question.
%
% Usage, with \Lopt{perquestionmarks}:
% \begin{quotation}
%   \noindent
%   |\begin{question}|\oarg{questionnumber}\marg{marks}\\
%   \dots\\
%   |\end{question}|
% \end{quotation}
% Or, with \Lopt{noperquestionmarks}:
% \begin{quotation}
%   \noindent
%   |\begin{question}|\oarg{questionnumber}\\
%   \dots\\
%   |\end{question}|
% \end{quotation}
%
% There are two variants of this environment, depending on whether the
% \Lopt{perquestionmarks} option is present or not.  If it is present
% (the default) then the \Lenv{question} environment takes a non-empty
% argument showing the total marks available for a question.
% In addition, the class checks that the |\partmarks| commands within the
% question (see below) add up to this declared goal mark.
% If the \Lopt{showmarktotals} option is present, then this (expected and
% checked) total is displayed at the end of the question.
%
% If the \Lopt{perquestionmarks} option is \emph{not} present,
% then questions have no individual marks, the
% environment takes no marks argument, and no marks are shown (this is usual
% in essay-question exams, which typically comprise a sequence of
% short equal-valued questions with an explanatory rubric).
% Also, in this case the |\partmarks| command cannot be used within the question.
%
% The \Lenv{question} environment takes an optional argument, giving
% the expected question number.  In \Lopt{compose} mode, this is used
% as the question number (unsurprisingly).  In the two other modes,
% this is compared with the question number which would be generated based on the
% position in the sequence of \Lenv{question} environments in the file, so
% that the first \Lenv{question} environment is for question one, the
% second for question two, and so on.  If these do not match, the exam
% class displays a warning in \Lopt{draft} mode, and produces a fatal
% error in \Lopt{final} mode.
% The intention is that this can act as a check that all expected
% questions are present; see also the |\numquestions| command.
% \iffalse XXX How useful is this in fact? Should I just discard this,
% especially since includequestion has a similar features? \fi
%
% \DescribeMacro{\QuestionNumberChecksOff}
% In some cases, the questions are not numbered in this
% straightforward fashion, so that you might have questions~`2A'
% and~`2B'.  In this case, the check is not meaningful, and you must
% suppress it by calling the macro |\QuestionNumberChecksOff| in the
% preamble.  After that, you must provide a question-number argument
% (in square brackets) for every question.
%
% Using |\label| within a question sets a label for the question number;
% using it within a |\part| (see below) labels the part number.
%
% In some odder circumstances, you might not want to have any question
% numbers at all; for example, you might want to require examinees to
% attempt \emph{all} of the questions, and so simply have a mark for
% the whole exam.  There isn't a mode for this as such, but if you use
% the \cs{QuestionNumberChecksOff} macro, and give |[\space]| as the
% optional `question number' at the beginning of the \Lenv{question}
% environment, then this will have the desired effect.
%
% \DescribeEnv{solution}
% The \Lenv{solution} environment, contained within the \Lenv{question}
% environment, contains the solution to the question, or other
% notes.  It is displayed by default in \Lopt{compose} mode, and
% suppressed by default in the others, though this behaviour may be
% overridden in either case with the \Lopt{(no)showsolutions}
% option.  You can have one \Lenv{solution} at the end of your
% question, or have multiple ones scattered throughout it.  You may
% use the |\partmarks| macro within the solution, to indicate the
% distribution of marks within (this part of) the solution --
% these, of course, do not count towards the total mark for the
% question.  You must not have a solution inside a solution.
%
% \DescribeEnv{questiondata}
% At the end of a question, it is frequently useful to include further
% information, such as extra equations, or numerical data.  These
% should be included within a \Lenv{questiondata} environment, in
% order for them to be formatted appropriately.  You may include
% multiple paragraphs, equations, and displays in this environment, as
% appropriate.  Typically, you will have only one such environment per
% question, appearing at the end, but may have several of them if you
% really wish to.
%
% \DescribeEnv{mcq}
% Some exams include multiple-choice questions rather than
% extended-answer ones.  These are numbered in the same sequence as
% the other questions, but are formatted and marked-up differently.
% \begin{verbatim}
%   \begin{mcq}
%   In 1908, where was there an airburst `impact'?
%   \answer Tunguska
%   \item Arizona
%   \item Off the Mexican coast
%   \item Egypt
%   \end{mcq}
% \end{verbatim}
% That is, the \Lenv{mcq} environment contains a list of possible
% answers, all of which are indicated by |\item|, except precisely one
% correct answer, indicated by |\answer|.
% \DescribeMacro{\multiplechoiceanswers}
% All multiple-choice questions must have the same number of possible
% answers, which is declared with the command \cmd|\multiplechoiceanswers{<n>}|
% The \Lenv{mcq} environment is permitted only after |\multiplechoiceanswers|.
% It's OK to have a \Lenv{solution} within an \Lenv{mcq} environment,
% which might provide further commentary on the correct answer.
%
% There are various other commands which you may or should use within
% the document.
%
% \DescribeMacro{\includequestion}
% It may be convenient to split your exam into a number of separate
% source files, such as having one \texttt{.tex} file for each
% question.  You can include these various source files using the
% usual |\input| command.
%
% If the separate source files have the simple form:\label{s:includequestion}
% \begin{verbatim}
%    \documentclass[compose]{exam-n}
%    \usepackage{graphicx} % for example
%    \begin{document}
%    \begin{question}
%    ...
%    \end{question}
%    \end{document}
% \end{verbatim}
% then they can be \LaTeX ed separately, for example by the authors of
% different questions, but cannot be |\input|
% unedited, as described above.  If, however, they have \emph{only}
% these structures (that is, only the |\documentclass| command,
% the \Lenv{document} environment, and zero or more |\usepackage|
% or |\RequirePackage| commands),
% then you can most conveniently import them unedited using the
% |\includequestion| command.
% \begin{verbatim}
% \includequestion{dynamics2}
% \end{verbatim}
% This acts like the |\input| command, but disables the listed structures.
% It also puts the included command into a group, so that any
% (re)definitions of commands are made local-only.
%
% Recall that the definition of the |\includequestion| command means
% that any |\usepackage| commands will be ignored.  If you, as a
% question author, need certain packages to be present for your
% question, you will have to make sure that whoever is assembling the
% master file includes those packages there, too.
%
% That is, we don't try too hard to support including just any old \LaTeX, here:
% any complicated preamble requirements in an included file should
% probably be managed by the exams convener transplanting them into
% the preamble of the main document.  This may be an overly
% simple-minded approach, and may change in future versions.
%
% The |\includequestion| command takes an optional argument which
% overrides the question number.  This caters for the case where
% question authors have (unhelpfully) included question numbers in the
% files' \Lenv{question} environments, and the case where questions
% are not numbered in a straightforward sequence, for example `1',
% `2A', `2B', and so on.
%
% \DescribeMacro{\section}
% \DescribeMacro{\subsection}
% Some exams are divided into sections, or have other structure which
% needs to be spelled out.  These are described with the |\section|
% command, in a form such as |\section{II}|.  You can also add smaller
% headers before individual questions with something like
% |\subsection{Second semester questions}|.  These can appear only
% between questions; it is an error to include one of these commands
% within a \Lenv{question} or \Lenv{mcq} environment.
%
% \DescribeMacro{\part}
%    Questions may be subdivided into parts, such as (a), (b),
%    (c)..., or (i), (ii), (iii), and so on.  Precede each of these with
%    this |\part| command.  The formatting of the part numbers is
%    controlled by the exam style, as customised in
%    \secref{s:custom}.  This macro starts a new paragraph.
%
%    You can use the |\part| macro within solutions: this is useful if
%    you have the entire \Lenv{solution} environment at the end of the
%    question, but distracting if you intersperse the \Lenv{solution}
%    environments between question parts.  The |\part| macro within
%    solutions increments separately from the increments within the question,
%    so if you use this in the solutions, you must have as many
%    |\part|s in the solution as there are parts in the question.
%
%    In some (rare) cases, you may want to force a particular part
%    number.  You can do that with an optional argument |\part[99]|
%    which overrides the auto-incremented numbering.  Note that this
%    skips the auto-increment of the number but doesn't cancel it, so
%    if you do this for one part number you should probably do it for
%    all of them.
%
% \DescribeMacro{\partmarks}
% \DescribeMacro{\partmarks*}
%    Macros \cmd|\partmarks{<num>}| and \cmd|\partmarks*{<num>}| announce
%    the number of marks associated with the current part of a question.
%    The class checks that the number of marks here does add up to the
%    number declared at the beginning of the {question} environment.
%    You will typically have just one |\partmarks| per |\part|, but
%    you can have more if you want.
%
%    The |\partmarks| command will most typically go at the end of a
%    paragraph, but it may also appear inside an equation (that is, in
%    |\[...\]|; don't use |$$...$$|), inside one or other
%    \Lpackage{amsmath} display or \Lenv{equation} environments, or in
%    a list or other environment.  If it appears
%    inside an environment, the indicator will appear at the
%    \emph{end} of the environment, independent of where in the
%    environment the command was typed (which implies that you can't
%    have more than one inside an environment).  The alignment of
%    the partmarks indicator is not currently as good as I'd like it
%    to be, in the case of \Lpackage{amsmath} alignments, but this
%    turns out to be hard to improve.
%
%    The starred version is similar, but budges its indicator upwards
%    a little, and is a heuristic alternative which is useful in some
%    cases \emph{after} a list or display, if the placement of the
%    indicator is otherwise inaesthetic
%    (if the style of the part-marks indicators happens to be such
%    that the indicator may be mistaken for an equation number, then
%    it would be wise to use either |\partmarks| or |\partmarks*|
%    after the equation, instead).  If you use |\partmarks*| within a
%    display, you might be confronted by an error message, talking
%    about |\eqno| in maths mode, which is even more incomprehensible
%    than most \LaTeX\ messages.
%
%    The unstarred version should only be used at the end of a
%    paragraph, and in fact forces a paragraph end; the starred
%    version should on stylistic grounds generally be used only at the
%    end of a paragraph, but it doesn't force one.
%
% The |\partmarks| command has an optional argument which
% indicates the category of the question, thus `bookwork', `unseen',
% and so on.  If this is present, then the category is included in the
% marks indicator.
%
% The |\partmarks| category/comment will typically be only one or two words
% long, and can sit comfortably in the margin.  If an author wants to
% write more here, then it will be turned into a footnote on the
% page.  This will obviously change the layout of the page, though
% since this text appears only in \Lopt{showsolutions} mode, that
% shouldn't be a problem.
%
% \DescribeMacro{\defaultpartmarkscategory}
% If the exams convener wishes to \emph{oblige} people to
% include such a category, then they might call
% |\defaultpartmarkscategory{category?}| in a package-options (|.clo|)
% file, to default the category with a highlighted remark to the question setter.
%
% \DescribeMacro{\comment}
%    \cmd|\comment{<text>}| associates a comment with a part of the text.
%    This is ignored in \Lopt{final} mode, but appears in the margin in the
%    other modes.
%
% \DescribeMacro{\author}
%    The |\author| command is a convenience.  Used within a
%    \Lenv{question} environment -- most naturally just after the
%    |\begin{question}| -- it creates a comment with the author's
%    name.  Its functionality may be expanded in future, so you should
%    use this command, rather than a generic |\comment|, when noting
%    the authorship of a question.
%
% \DescribeMacro{\shout}
% If there is part of a question which is, for example, incomplete,
% and which needs a more prominent callout than `comment', then you
% should |\shout{...}| it.  Shouts appear in all modes (\emph{including}
% \Lopt{final}) and appear whether or not the class is showing solutions.
% This makes a prominent remark in the text, and also in a list of
% shouts at the end of the text.  Your co-authors, or the exam
% proof-checker, really have no excuse for missing it after that.
%
% \DescribeMacro{\leftnudge}
% For various reasons, most often because of printing problems, it can
% be useful to nudge the textblock left or right a little.  You should
% call the |\leftnudge| command to do this, rather than fiddling with
% the underlying \LaTeX\ dimensions yourself.  Give the command a dimension
% argument such as |\leftnudge{1cm}| to nudge the textblock leftwards
% by 1cm.  You can give a negative dimension to nudge it rightwards
% instead.  The \Lopt{draft} option automatically nudges the text
% block leftwards, to create a larger right-hand margin for notes.
%
% \DescribeMacro{\questionpreamble}
% If |\questionpreamble| is called, then its contents are displayed
% just before the start of the next question.  This is useful for text like
% |\questionpreamble{And one of\dots}| which might reinforce information in
% the examination rubric.
%
% \subsection{Preamble}
% \label{s:preamble}
%
% \DescribeMacro{\exambanner}
% The |\exambanner| macro supplies text like `Examination for the
% degrees of\dots'.
% Since the contents of this command is automatically uppercased in
% some styles, and there are per-department specifics about the punctuation
% of abbreviations, you should use the commands |\BSc|, |\MSci|, and
% friends (see \secref{s:othercommands}) to set the degree names
% appropriately.
%
% \DescribeMacro{\universitycoursecode}
% \DescribeMacro{\degreedescriptions}
% \DescribeMacro{\coursetitle}
% Declare the identity of the exam with
% |\universitycoursecode|, |\schoolcoursecode|, |\coursetitle| and
% |\degreedescriptions|.  The distinction between these is as follows:
% \begin{description}
% \item[University course code]
%     This is the code for the course (and thus for the paper) as it
%     appears in university information systems, and is a
%     university-unique code such as `PHYS3031'.
% \item[Course title]
%     This is just a textual name for the course, for example `Quantum Mechanics'.
% \item[Degree descriptions]
%     This is a textual description of the qualifications that the
%     students doing this exam are heading for.  This text has little
%     formal weight, but might help a lost student realise they're in
%     completely the wrong exam room\dots.  This is something like
%     |{Physics 3\\Chemical Physics 3}| (separate each description
%     using |\\|).
% \end{description}
% All of these are required elements, and the \LaTeX\ compilation will
% halt if they are absent.  If for some reason the exam
% paper does not need these to be present -- perhaps it is a class
% test, for example -- then give the class option
% \Lopt{sloppydescription}, and the checks for these elements (and for
% |\rubric|) are suppressed.  The layout may end up looking a little
% funny.
%
% \DescribeMacro{\schoolcoursecode}
% There is also a command |\schoolcoursecode|, which is a more
% informal, but possibly more recognisable, code for the course/paper,
% as it is generally recognised within the school; for example, the
% honours Quantum Mechanics course is known within the school as
% P304H.  Its use is optional.
%
% \DescribeMacro{\paperident}
% It can be convenient to add some identification to each page, if for
% no other reason than to double-check that you haven't inserted a
% field theory question into an `astronomy for poets' exam.  The command |\paperident|
% allows you to declare some text which appears at the bottom of each
% page of the exam.  It will typically repeat some of the text in the
% |\schoolcoursecode| or |\degreedescriptions| arguments.
% This is generally not necessary, however, as in its absence the
% class generates an identifier.  This identifier contains the name of
% the exam, plus a pair of counters (for example \emph{QM2/98-1177}).  The
% function is two-fold: (i) since the counters increase monotonically
% (they actually encode the date and time when the document
% was \LaTeX ed), you can tell which of two superficially similar
% documents is the later; and (ii) if you drop a sheaf of papers on the
% photocopier floor, you can work out which one is which.
%
% \DescribeMacro{\examdate}
% \DescribeMacro{\examtime}
% Give the date and time of the exam with |\examdate| and |\examtime|.
% Sometimes an exam may
% have different time limits for different qualifications: this case,
% separate the various times with |\\|, as in
% \cmd|\examtime{9.30am -- 12 noon\\ (or) 9.30am -- 1.45am}|.
%
% \DescribeMacro{\rubric}
% \DescribeMacro{\norubric}
% The rubric, provided unsurprisingly by the command |\rubric|, may
% contain more than one paragraph,
% delimited by the usual blank line.  Any emphasised words should be
% marked with |\emph| -- they are typically
% emphasised with a bold font.  The class checks that a rubric has
% been specified (unless \Lopt{sloppydescription} is present); if you
% really wish to suppress this rubric -- perhaps because the
% |\baserubric| is sufficient -- then give the command |\norubric|.
% \DescribeMacro{\baserubric}
% As well as this exam-specific rubric, the style produces an additional
% boilerplate rubric, containing the usual material such as `Do not on
% any account attempt to write on both sides of the paper at once.
% Calculations may be done on the fingers, but candidates should avoid
% counting on their toes unless special permission has been obtained beforehand.'
% You will typically not have to change this, but if you do for some
% reason, you can override it with the |\baserubric| command.
%
% Note that the |\baserubric| command is typically used within a |.clo|
% file, within the argument to |\OverrideFormatting|.  If you wish to
% further override this on a per-exam basis, then you will need to do
% so after |\OverrideFormatting| has done its work, and thus
% immediately after the |\begin{document}|.
%
% \DescribeMacro{\numquestions}
% Finally, declare the number of questions which are to be in the
% paper with |\numquestions|.
% The class issues a warning if we don't have this number, in draft or
% final mode.  This is optional -- no check is done if this isn't present.
%
%
% \subsection{Other useful commands}
% \label{s:othercommands}
%
% \DescribeMacro{\BSc\ and friends}
%    Macros |\BSc|, |\MSci|, |\MSc|, |\MA|, |\MEng| and |\BEng| are used
%    within the preamble macros to give appropriately capitalised and punctuated
%    versions of the degree types.
%
% \DescribeMacro{\vec}
%    Macro |\vec| is redefined to give bold-font vectors, rather than
%    vectors with arrows, which is the (weird) \LaTeX\ default.  This
%    should work for bold greek as well as roman.
%
% \DescribeMacro{\dd}
%    Macros |\dd| and |\ddd|: |\dd| is a roman d, as used for
%    differentials; |\ddd| is the same with a preceding thinspace,
%    as used within integrals; for example
% \[
%  |\int f(x)\ddd x = \int f(x)\,\dd x| = \int f(x)\ddd x
% \]
%
% \DescribeMacro{\Diffl}
%    You can typeset derivatives neatly:
%    \begin{center}
%    \def\dd{\mathrm{d}}
%    \begin{tabular}{ll}
%    |\Diffl{a}{b}|     & $\displaystyle \Diffl ab$ \\[2ex]
%    |\Diffl[2]{a}{b}|  & $\displaystyle \Diffl[2]ab$\\[2ex]
%    |\Diffl*{a}{b}|    & $\Diffl* ab$ \\
%    |\Diffl*[2]{a}{b}| & $\Diffl*[2]ab$\\
%    \end{tabular}
%    \end{center}
%    The unstarred versions are for displayed equations, the starred
%    ones for inline maths.
% \DescribeMacro{\Partial}
%    There is analogous support for partial derivatives with |\Partial|.
%
% \DescribeMacro{\units}
%    You should generally type units, and numbers with units, using
%    the \Lpackage{siunitx} package, which is loaded by the
%    \Lopt{siunitx} option (which is now enabled by default).  However
%    this class currently also supports a basic |\units| command,
%    described below.  This macro will be removed in a future version
%    of the class.
%
%    Macros |\units|, |\units*|:  you can typeset physical units in
%    |\rm|, with tilde or dot
%    acting as a separator between units.  Since this is typeset in maths mode, all
%    other spacing is ignored.  The unstarred version includes
%    leading |\thinspace|, as in |$v=10\units{m.s^{-1}}$|, giving
%    $v=10\units{m.s^{-1}}$.  The starred
%    version can be used when referring to the unit by itself
%    (eg axis is |$B/\units*T$|, or $B/\units*T$), and is not
%    qualifying a number.
%
%    \def\cs#1{$\backslash$\texttt{#1}}
%    For other useful symbols, see table~\ref{t:symbols}.\footnote{The
%    package used to support an \cs{au} macro, for astronomical
%    unit, and \cs{lambdabar} for Compton wavelength, but these have
%    since been removed.  The former is available via
%    \Lpackage{siunitx}.}
%
% \begin{table}
% \hrule \medskip
% \begin{tabular}{rlp{8cm}}
%    |\e|&$\e^{i\pi}=-1$& the exponential is typeset in an upright rather than
%    italic shape, as in |$\e^{i\pi}=-1$|.\\
% \end{tabular}
% \caption{\label{t:symbols}Miscellaneous symbols}
% \medskip\hrule
% \end{table}
%
%
% \section{Customising the exam style}
% \label{s:custom}
%
% As described in \secref{s:options} above, any unrecognised
% options are interpreted as an instruction to search for and include
% a class options file, formed from the name of the unrecognised
% option, suffixed with \file{.clo}, which can be anywhere in the
% \TeX\ include path.  This options file has a fair amount of leeway
% to override and adjust the layout of the exam.
%
% The most typical changes here will be to adjust the exam rubric for
% a particular class, with the command |\baserubric|, and to change the
% sheet of physical constants, with the command |\constantssheet|.
% See the sample file |myclass.clo| for examples.
%
% Examine this sample \file{SpecialExam.clo} file:
% \begin{verbatim}
% \typeout{Physics Special exam options, for Special people}
% \ExecuteOptions{pageperquestion}
%
% \OverrideFormatting{
% \renewcommand\FormatPartMarks[1]{\{#1\}}
% \renewcommand\FormatPartNumber
%   {\hbox to 0pt{\hss (\StylePartNumber{partnumber})\hskip1em}}
% \let\StylePartNumber\roman % as opposed to \alph
% \renewcommand\FormatQuestionNumber
%   {\hbox to 0pt{\hss \textbf{\@currentquestion}\hskip2.5em}}
% }
%
% \constantssheet{
%    \begin{center}
%    $E=mc^2$ and $c=3\times10^8 {\rm m\,s^{-1}}$
%    \end{center}
% }
% \end{verbatim}
% This announces itself, then invokes the exam style's \Lopt{pageperquestion}
% option.
%
% It then includes a number of formatting adjustments,
% enclosed within the |\OverrideFormatting| command; the formatting
% hooks are described below.
%
% Then it declares a `constants sheet', which is a display of
% constants or equations, or indeed anything else, which is to be
% displayed on the second page of the exam.
%
% The available formatting hooks are as follows:
% \begin{description}
%
% \item[FormatPartMarks]
% This formats the indication of the marks carried by a particular
% part of a question.  In this case, we have chosen to have the marks
% contains inside curly brackets, rather than the default square
% brackets.  By default, the part-marks text will be placed at the end
% of the paragraph it completes, flush right, and with at least 2em of
% space before it.  You can change this default space with
% |\@partmarksspace|; as a special case, you can have the text sitting
% in the margin instead, by having |\FormatPartMarks| generate a
% zero-width box, and setting |\@partmarksspace=0pt|.
%
% \item[FormatPartNumber]
% This overrides how to format the various |\part| markers within a
% question, using the \texttt{partnumber} counter.  In this case, the
% markers will jut into the left-hand margin, rather than being
% run-in.
%
% \item[StylePartNumber]
% This overrides how to style the |\part| markers.  The default is
% |\alph|, but you might prefer, for example, |\Roman| or |\arabic|.
% Override this with |\let\StylePartNumber\Roman|.
%
% \item[FormatQuestionNumber]
% If you adjust the part marks, you should probably adjust the
% formatting of the question number also.
% \end{description}
%
% If you really want to go to town on reformatting, you can redefine
% the command |\maketitle|, which formats the front-page title.  When
% formatting this, you have access to each of the fragments of text
% described in \secref{s:preamble}, via a macro named after the
% corresponding command.  Thus the argument of the |\exambanner| command
% is available in the macro |\@exambanner|.  The exception is
% |\numquestions|.  If you find yourself needing to do this, it might
% be worth having a discussion with the style's maintainer -- there
% may be a simpler way to get what you want.
%
% \DescribeMacro{\CheckExamMetadata}
% One of the things you may change within the |\maketitle| is the
% checking of exam metadata -- which fields are required and which are
% optional.  You can change these from the default (in
% \secref{s:preamble}) by defining a command |\CheckExamMetadata|.
% \DescribeMacro{\RequiredMetadata}
% This macro takes no arguments, and should use the command
% \cmd|\RequiredMetadata{<field>}{<description>}{<help-text>}| to
% perform its tests.
% {\catcode`\<=\active Here <field> is the metadata key, such as
% |{examdate}|, which corresponds to the macro |\examdate|, <description> is
% a brief description of the field, such as |{exam date}|, and
% <help-text> is a longer bit of explanation.  If the corresponding
% data is missing, then \LaTeX\ stops with an error, and the user can
% examine the <help-text> by pressing the \texttt h key.  You can
% adjust the test by examining the value of
% |\iffussydescription ... \fi|, which is set to |\false| if the \Lopt{sloppydescription}
% option was provided.}
%
% No more clues.  If you want to hack at this, see the definition of
% |\maketitle| in the class file \file{exam-n.cls}.
% Aspire not to break things.

% \iffalse %%%CONFIGURE%%% change the following to iffalse for a locally-distributed version\fi
% \iftrue
% \section{A work-flow}
% This class file was developed as part of a move to `\LaTeX ify' the
% production of exams in the School of Physics and Astronomy, in the
% University of Glasgow.  The work-flow which emerged was, roughly, as
% follows:
% \begin{enumerate}
% \item The exam convener (the person in charge of assembling the exam
% for a given course or lecture series) creates a Sharepoint directory
% which contains a master file
% (which consists mostly of |\includequestion| macros),
% plus subdirectories each containing a short template file for the
% benefit of question authors, and a copy of the
% \texttt{notes-for-authors.pdf} instructions.
% \item Each of those `question' directories is made visible to, and
% read-writable by, the lecturer responsible for that question.  They
% write and \LaTeX ed their question, and upload it back to
% Sharepoint.
% \item The exam convener, who has access to the whole tree of
% questions, downloads or network-mounts the Sharepoint folder, and
% either edits the questions or negotiates with the authors, until
% the exam \LaTeX s successfully.  The result can then be
% snapshotted, and sent off to the external examiner.
% \end{enumerate}
% This provides a centralised and easily manageable repository
% for a previously fiddly and error-prone process.
%
% In step one, the template file is just one with a \texttt{[compose]}
% option, following the brief example on p.\pageref{s:includequestion}.
% We had excellent secretarial help to manage this step; it was fiddly the
% first couple of times, but largely mechanical thereafter.  In Sharepoint,
% this step can in principle be automated, though we concluded this
% was unnecessary in our case.
%
% Sharepoint (possibly slightly surprisingly) worked smoothly for us;
% in other circumstances a group-writable source code repository, or
% an institutional CMS, or even just a shared drive, would work just
% as well.  The advantage of Sharepoint, from our point of view, was
% that it integrated with the university's existing authentication
% framework, and was (axiomatically) acceptably secure for the process
% of creating exams.
%
% The majority of our authors were habitual users of \LaTeX\ for
% writing journal articles, and with subsequently submitting them to
% journals or the arXiv; and when the process was presented in
% those terms, with the same advantages, it was readily accepted.
%
% Thanks to Graham Woan and Rachael MacLaughlan for the numerous
% iterations of this process until both it and the class file were stable.
% \fi

% \section{Example}
%
% Here is a short example file.  There are further examples in the
% \texttt{sample/} directory of the distribution.
%    \begin{macrocode}
%<*example>
%%%START example (Makefile strips out this block)
\documentclass{exam-n}  % standard final version
%%\documentclass[draft,showsolutions]{exam-n}  % draft style, showing solutions
%%\documentclass[compose]{exam-n}  % compose (author's) style

\examdate{Wednesday, 18 May 2005}
\examtime{9.30am -- 12 noon\\(or) 9.30am -- 1.45am}

\exambanner{Examination for the Degrees of \BSc(Science) and
  \MSci\ on the Honours Standard}
\schoolcoursecode{P304D and P304H}
\universitycoursecode{PHYS3031 and PHYS4025}
\coursetitle{Quantum Mechanics}
%\degreedescriptions{Physics 3, Chemical Physics 3, Physics with
%  Astrophysics 3, Theoretical Physics 3M, Joint Physics 3}
\degreedescriptions{Physics 3\\Chemical Physics 3\\Physics with
  Astrophysics 3\\Theoretical Physics 3M\\Joint Physics 3}
\paperident{GR/P304}

\rubric{Candidates for examination in \emph{Quantum Mechanics} should
  answer question 1 (16 marks) and \emph{either 2A or 2B} (24 marks each)}

\numquestions{3}

\begin{document}
\maketitle

\section{I}

\begin{question}{20}
\part At various points in the development of the mathematical theory of
General Relativity, we pick a coordinate system in which
differentiation is simple, and do a calculation using non-covariant
differentiation, indicated by a comma.  We then immediately deduce the
covariant result, replacing this comma with a semicolon.

Separately, the strong equivalence principle is sometimes
referred to as the `comma goes to semicolon' rule.

Explain the logic of each of these replacements of a comma with a
semicolon, putting particular stress on the distinction between
them.\partmarks{10}

\part The radial and angular coordinates, $r$ and $\phi$ respectively,
of a test particle moving in the Schwartzschild metric exterior to a
star of mass $M\ll r$, are related by the equation
\[
  r = \frac{h^2}M \left(
        1 + e\cos\phi + \frac{3M^2}{h^2}e\phi\sin\phi
        \right)^{-1},
\]
where $h$ and $e$ are constants.  Show that this equation takes the
form of a precessing ellipse, of semi-latus rectum $l=h^2/M$, in which
the pericentre line advances each orbit by an amount
$\Delta=6\pi M^2/h^2$, stating clearly any assumptions that
you make.\partmarks{6}

The solar-mass star HD83443 has a 0.35 Jupiter-mass planet that
follows a circular orbit of period 2.986 days and radius \SI{0.038}{\astronomicalunit}.
Calculate the rate of precession, in arcseconds per year, of the
pericentre line of the planet's orbit.\partmarks{4}

[Schwartzschild radius of the Sun: \SI{3e3}m; $\SI1\astronomicalunit = \SI{1.5e11}m$]

\begin{solution}
  In the first type of calculation, we do a calculation in the LIF, in
which~$\Gamma^i_{jk}=0$, so that single partial differentiation is the
same as covariant differentiation.  If this process produces a
geometrical object such as a scalar or a tensor, then we know that the
result is frame-invariant.  If the result involves only single partial
differentiation -- that is, no second derivatives -- then since
partial differentiation is the same as covariant differentiation in
these coordinates, we cannot distinguish partial and covariant
derivatives, and can replace the commas by semicolons.  Since these
are now manifestly covariant derivatives, so that the result is a
tensor, and thus frame-invariant, the same expression would be true in
any frame.

The second situation is the statement that the expressions of physical
laws in SR, such as the conservation equation
$T^{\mu\nu}_{,\nu}=0$, must take the same \emph{form} when written
as a covariant equation in GR, crucially without any curvature
coupling.  The slogan `comma goes to semicolon' is just a mnemonic for
this.

The distinction is that the first is a mathematical trick, of sorts,
whereas the second is a version of the equivalence principle, and thus
a statement with deep physical content.

They don't have to explain things at this length or with this
coherence (?) to get quite a few marks.  They just have to show they
have a clue.
\end{solution}
\end{question}

\end{document}
%%%END example
%</example>
%    \end{macrocode}
%
% \section{Release notes}
% Recent release notes are below.  For older notes, see the source
% distribution.
%
% \input{release-notes.dtx}
%
% \subsection*{Acknowledgements}
% \addcontentsline{toc}{subsection}{Acknowledgements}
%
% This class has greatly benefitted from comments and bug-reports from
% Harry Ward, Graham Woan, and Nicolas Labrosse;
% and it has received code contributions from Morag Casey.
%
% \StopEventually{}

% \section{Implementation}
%
% \subsection{\LaTeX3 compatibility}\label{s:compatibility}
%
% As of release 1.4.0, we depend on the \LaTeX3 hooks mechanism, which
% was introduced in 2020.  We therefore cannot work with versions
% older than that.
%
% Note that we can't use the (apparently preferable)
% |\IfFormatAtLeastTF| command to do this test: we want to continue to
% work even when we're using a \LaTeX\ which is too old for this
% command to be defined.
%    \begin{macrocode}
\@ifl@t@r\fmtversion{2020/10/01}
                    {\typeout{Format is \fmtversion -- OK!}}
                    {\ClassError{exam-n}
                      {You need a more recent version of LaTeX}
                      {This class now requires a
                        LaTeX version at least 2020/10/01; version
                        \fmtversion\ is too old}}
%    \end{macrocode}
%
% \subsection{Options}
%
% First, process the compose/draft/final option.
% Flag |\@draftstatus| 0 represents the final version; 1 is a draft exam; 2 is a
% single question being composed
%    \begin{macrocode}
%<*package>
\newcount\@draftstatus
\@draftstatus=0 % default is final
\DeclareOption{compose}{\@draftstatus=2
  \@showsolutionstrue
  \@pageperquestiontrue}
\DeclareOption{draft}{\@draftstatus=1
  \@showsolutionstrue
  \@pageperquestionfalse}
\DeclareOption{final}{\@draftstatus=0
  \@showsolutionsfalse
  \@pageperquestionfalse}
%    \end{macrocode}
%
% Set true to use PostScript fonts
%    \begin{macrocode}
\newif\if@psfonts\@psfontsfalse
\DeclareOption{psfonts}{\@psfontstrue}
\DeclareOption{cmfonts}{\@psfontsfalse}
%    \end{macrocode}
%
% Given that we're using PS fonts, should we use the mathtime fonts,
% rather than just the mathptm ones (which aren't really ideal)?  It
% turns out that we can't test for the presence of the mathtime fonts
% from within this class file -- the only reliable way of checking if
% they're present is to look for something like rmtmi.pfa, but
% |\IfFileExists| isn't able to search for any of those files, only ones
% on the \texttt{TEXINPUTS} path such as \texttt{mathtime.sty}, which can be, and are
% often, installed without the fonts themselves being present.
%    \begin{macrocode}
\newcount\examn@mtselect \examn@mtselect=0
\DeclareOption{mathptm}{\@psfontstrue\examn@mtselect=0}
\DeclareOption{mathtime}{\@psfontstrue\examn@mtselect=1}
\DeclareOption{mtpro2}{\@psfontstrue\examn@mtselect=2}
\DeclareOption{stix2}{\@psfontstrue\examn@mtselect=3}
%    \end{macrocode}
%
% The letter $\pi$ is usually the circular constant, and as such
% should be set in an upright greek font.  Don't this by default,
% since that goes against the usual \LaTeX\ default, but instead
% define the [uprightpi] option to support this, where possible.
% Not all fonts make this easy.
%    \begin{macrocode}
\newif\ifexamn@uprightpi \examn@uprightpifalse
\DeclareOption{uprightpi}{\examn@uprightpitrue}
%    \end{macrocode}
%
% Load the \Lpackage{siunitx} package, or not, defaulting yes.
% This is now preferred to the |\units| macro, and the latter will be
% removed in a forthcoming release.
%    \begin{macrocode}
\newif\ifexamn@siunitx \examn@siunitxtrue
\DeclareOption{siunitx}{\examn@siunitxtrue}
\DeclareOption{nosiunitx}{\examn@siunitxfalse}
%    \end{macrocode}
%
% Switch between serif and sans serif fonts.  We make little attempt
% to make the latter attractive; this is purely to conform to the
% superstition (there seem no more grounds than that) that this is
% better for dyslexic students.
%    \begin{macrocode}
\newif\ifexamn@serif
\examn@seriftrue
\DeclareOption{serif}{\examn@seriftrue}
\DeclareOption{sansserif}{\examn@seriffalse}
%    \end{macrocode}
%
% Set |\if@showsolutions| true if we are to show the contents of {solution} environments
%    \begin{macrocode}
\newif\if@showsolutions
\@showsolutionsfalse
\DeclareOption{showsolutions}{\@showsolutionstrue}
\DeclareOption{noshowsolutions}{\@showsolutionsfalse}
%    \end{macrocode}
%
% Set |\if@pageperquestion| true if we want a new page after each question
% (set when printing solutions)
%    \begin{macrocode}
\newif\if@pageperquestion
\@pageperquestionfalse
\DeclareOption{pageperquestion}{\@pageperquestiontrue}
\DeclareOption{nopageperquestion}{\@pageperquestionfalse}
%    \end{macrocode}
%
% Set |\if@perquestionmarks| true if we are to expect a marks total to
% be specified in the question, subtotals to be specified in the
% question, and to include a check, at the end, that the two match up.
%    \begin{macrocode}
\newif\if@perquestionmarks
\@perquestionmarkstrue
\DeclareOption{perquestionmarks}{\@perquestionmarkstrue}
\DeclareOption{noperquestionmarks}{\@perquestionmarksfalse}
%    \end{macrocode}
%
% Set |\if@showmarktotals| true if we are to display the expected (and
% checked to be actual) total marks at the end of the question.
%    \begin{macrocode}
\newif\if@showmarktotals
\@showmarktotalstrue
\DeclareOption{showmarktotals}{\@showmarktotalstrue}
\DeclareOption{noshowmarktotals}{\@showmarktotalsfalse}
%    \end{macrocode}
%
% Support the standard article oneside/twoside options, even though
% they do nothing in this class.
%    \begin{macrocode}
\newif\if@twosidepages
\@twosidepagesfalse
\DeclareOption{twoside}{\@twosidepagestrue}
\DeclareOption{oneside}{\@twosidepagesfalse}
%    \end{macrocode}
%
% Some options styles want \Lopt{fleqn}, so make it an option to this
% class, to be passed on to article and amsmath.
%    \begin{macrocode}
\newif\if@fleqn
\@fleqnfalse
\DeclareOption{fleqn}{
  \@fleqntrue
  \PassOptionsToPackage{fleqn}{amsmath}
  \PassOptionsToClass{fleqn}{article}
}
%    \end{macrocode}
%
% If \Lopt{sloppydescription} is given, then we don't demand that all
% the required exam metadata is provided.  Failing this, we object, fatally, to
% missing information.
%    \begin{macrocode}
\newif\iffussydescription
\fussydescriptiontrue
\DeclareOption{sloppydescription}{\fussydescriptionfalse}
%    \end{macrocode}
%
% The university logo is typeset in colour by default; the \Lopt{mono}
% option causes everything to be in mono instead.  The \Lopt{colour}
% option does nothing, but is present for symmetry.  These have to be
% |\def|s, by the way, not |\let|s, since the size macros aren't
% defined until after \Lpackage{article} has been loaded.  It seems
% prudent to make the `showing solutions' text a bit more shouty in
% this monochrome case.
%    \begin{macrocode}
\def\examn@header@shoutformat#1{{\Large\bfseries #1}}
\DeclareOption{mono}{
  \PassOptionsToPackage{monochrome}{xcolor}
  \def\examn@header@shoutformat#1{{\Huge\bfseries #1}}
}
\DeclareOption{colour}{}
%    \end{macrocode}
%
% Options \Lopt{largefont} and \Lopt{hugefont} print versions of the
% exam in `big' or `huge' font sizes, to help students with visual impairments.
% The available font variants are represented as numbers.
% Note: the |\examn@fontvariant| mechanism is in principle more
% general than simply size variants, but some of the code below
% assumes that |\examn@fontvariant| greater than zero means large
% text, and so would need to be adjusted if this becomes untrue.
%
% The flag |\ifbigfont| is true if the font is `significantly large',
% in the sense that exam text, or hyphenation or layout, may have to
% be adjusted in this case:
% option \Lopt{hugefont} sets it true, option \Lopt{largefont} does
% not.  It's intended to be a user-visible and -settable flag.
%
% \emph{Note:} the \Lopt{hugefont} option used to be \Lopt{bigfont};
% the latter is deprecated and may be removed in v1.2.
%    \begin{macrocode}
\newcount\examn@fontvariant
  \examn@fontvariant=0 % the default
\newif\ifbigfont
  \bigfontfalse
\DeclareOption{largefont}{\examn@fontvariant=1 \bigfontfalse}
% Deprecate [bigfont]; consider removing in v1.2
\DeclareOption{bigfont}{%
  \ClassWarning{exam-n}{OPTION [bigfont] HAS BEEN DEPRECATED; use [hugefont] instead}
  \examn@fontvariant=2 \bigfonttrue}
\DeclareOption{hugefont}{\examn@fontvariant=2 \bigfonttrue}
%    \end{macrocode}
%
% This class is based on the article class.  Load it, and pass the \texttt{a4paper}
% option to it.
%    \begin{macrocode}
\PassOptionsToClass{a4paper}{article}
%    \end{macrocode}
%
% We allow \file{.clo} files to override elements of the formatting,
% such as |\maketitle| and the various |\Format...| hooks.  They must
% do this within a |\OverrideFormatting| command, using a sequence of
% |\renewcommand|s.  Carefully.
%    \begin{macrocode}
\newtoks\@styleoverrides
\@styleoverrides={}
\def\OverrideFormatting{\@styleoverrides=}
%    \end{macrocode}
%
% There are a few other settings which may be defaulted within a
% \file{.clo} file:
% \begin{itemize}
% \item |\constantsheet{...}|: is a table of, for example, physical
% constants which should appear in exams associated with a particular
% course.  Despite the name, this can be any text which should appear
% on the first non-cover sheet of the exam.
% \item |\baserubric|: a modified `base rubric' -- see the
% documentation of |\rubric| below.
% \end{itemize}
%
% If \@constantssheet is defined (using |\constantsheet{...}| in a
% .clo file), then display it on a page by itself.
%    \begin{macrocode}
\newtoks\@constantstoks
\def\@@displayconstants{%
  \clearpage
  \begingroup
  \the\@constantstoks
  \endgroup
  \clearpage }
%    \end{macrocode}
% The macro |\constantssheet| has to be declared here, rather in the
% more natural place below, with \@exambanner and friends, so that
% it's usable within .clo files.
%    \begin{macrocode}
\newtoks\@constantstoks
\@constantstoks={}
\let\@displayconstants\relax
\def\constantssheet{\let\@displayconstants\@@displayconstants
  \@constantstoks=}
%    \end{macrocode}
%
% Similarly for the |\baserubric| and |\rubric| commands.
%
% The rubric is typically a per-exam thing.  The `base rubric' is
% more-or-less common to all exams, though it's possible to override
% it in a .clo file.
%    \begin{macrocode}
\def\@rubric{}
\def\rubric{\long\def\@rubric}
\def\norubric{\let\@rubric\@nnil}
%    \end{macrocode}
% \dots and the base rubric:
%    \begin{macrocode}
\def\@baserubric{%
\textbf{Answer each question in a separate booklet}\par
Candidates are reminded that devices able to store or display text or
images may not be used in examinations without prior arrangement.
\if@perquestionmarks
  \par
  Approximate marks are indicated in brackets as a guide for candidates.
\fi
}
\def\baserubric{\long\def\@baserubric}
%    \end{macrocode}
%
% The |\defaultpartmarkscategory| macro creates a default partmarks
% `category'.  See below.  This is declared here, so that it can be
% used in a |.clo| file without error.
%    \begin{macrocode}
\let\examn@defaultpartmarkscategory\relax
\def\defaultpartmarkscategory#1{\def\examn@defaultpartmarkscategory{#1}}
%    \end{macrocode}
%
% Spit out the style overrides at the beginning of the document,
% rather than here.
%    \begin{macrocode}
\AtBeginDocument{\the\@styleoverrides}
%    \end{macrocode}
%
% Any remaining options are interpreted as filenames, and the
% corresponding \file{.clo} file is read in.  We do not permit any
% other options, for example standard |{article}| options.
% There's a complication here (which I haven't resolved, to my
% puzzlement): if the .clo file includes for example
% |\ExecuteOptions{pageperquestion}|, then a \Lopt{nopageperquestion}
% appearing after the .clo option in the |\documentclass| line appears
% to be ignored or overwritten, which is odd, since I thought that
% options were executed in order; are these file options executed
% later than others, perhaps?
%    \begin{macrocode}
\DeclareOption*{\InputIfFileExists{\CurrentOption.clo}{}
  {\ClassError{exam-n}
    {Bad option \CurrentOption}
    {I don't understand the option \CurrentOption\MessageBreak
      (I didn't find file \CurrentOption.clo, if that's what you meant)}}}
%    \end{macrocode}
%
% The default options are set when the options are declared, above.
%
% If a file called \texttt{exam-n.config} exists, read it in.  It may
% usefully contain other |\ExecuteOptions{foo}| commands.  Note that
% these supplement but \emph{will not override} any options in the
% |\documentclass| command; thus these are really only useful for
% changing away from the default.  This last behaviour is
% unsatisfactory: it would be better if this would reliably override
% any options supplied in |\documentclass|, but that turns out to be
% hard to fix, given the \LaTeX\ option logic.
%    \begin{macrocode}
\InputIfFileExists{exam-n.config}{}{}
%    \end{macrocode}
% And finally process all the options marked so far.
%    \begin{macrocode}
\ProcessOptions
%    \end{macrocode}
%
% \subsection{Dependencies}
%
% We depend on the \Lpackage{article} class.
%
% Note: we have to do this this way, so that
% |\PassOptionsToClass{*side}{article}| is invoked only once --
% \Lenv{article} gets confused if both options are passed to it
%    \begin{macrocode}
\if@twosidepages
  \PassOptionsToClass{twoside}{article}
\else
  \PassOptionsToClass{oneside}{article}
\fi
\PassOptionsToClass{12pt}{article}
%    \end{macrocode}
%
% If the document includes
% the \Lpackage{graphicx} or \Lpackage{pdfpages} packages,
% then we don't want the \Lopt{draft} option to be passed on.
% So explicitly pass the \Lopt{final} option to these packages.
%    \begin{macrocode}
\PassOptionsToPackage{final}{graphicx}
\PassOptionsToPackage{final}{pdfpages}
%    \end{macrocode}
%
% %%%CONFIGURE%%%
% Define a logo for the University, which will appear in the exam header.
% This should be a macro which takes a single argument giving the
% required width of the logo, and which produces a |\vbox|.
%    \begin{macrocode}
\def\UniLogo#1{\vbox to 15.5mm{%
    \hrule
    \vss\hbox to #1{% Aspect ratio of logo is 100x31
      \hss no logo available\hss
    }%
    \vss
    \hrule}}
%    \end{macrocode}
%
% Other required packages.
%    \begin{macrocode}
\RequirePackage[english]{babel} % UK hyphenation
\RequirePackage{amsmath}
\ifexamn@siunitx
  \RequirePackage{siunitx}
\fi
%    \end{macrocode}
% We use the \Lpackage{xcolor} package, in preference to
% \Lpackage{color}, so that we are compatible with TikZ (TikZ loads
% the \Lpackage{xcolor} package internally, and that isn't compatible
% with \Lpackage{color}).  We could probably work around this some
% other way, but \Lpackage{xcolor} seems to be relatively standard,
% and appears to be backward compatible with \Lpackage{color},
% so this change is harmless.
%    \begin{macrocode}
\RequirePackage{xcolor}
%    \end{macrocode}
%
% I think flush-left equations look MUCH better than centred, but
% Harry disagrees, so it's not the default.
%    \begin{macrocode}
\LoadClass{article}
%    \end{macrocode}
%
% \subsection{Layout}
%
% \subsubsection{The \TeX\ engine}
% Identify the \TeX\ engine we're using.  If we are using pdf\TeX,
% Xe\TeX, or Lua\TeX, we presume we're generating PDF.  The
% \Lpackage{ifpdf} package exists, and evaluates to true for Lua\TeX,
% but doesn't distinguish between Xe- and Lua\TeX.
% It would be nice to use a package such as \Lpackage{iftex}, but (as of late
% 2017) this seems to do something sufficiently exotic with
% respect to |\if| nesting, that it confuses the logic here.
% It seems safer to do this test ourselves, so (a) we know what
% we're getting, and (b) we have the result in a convenient integer form.
%    \begin{macrocode}
\newcount\examn@engine
\examn@engine=0
\expandafter\ifx\csname pdfmatch\endcsname\relax
  \expandafter\ifx\csname XeTeXinterchartoks\endcsname\relax
    \expandafter\ifx\csname directlua\endcsname\relax
      \examn@engine=0 % this is presumably original-TeX (how unutterably retro!)
    \else
      \examn@engine=3
    \fi
  \else
    \examn@engine=2
  \fi
\else
  \ifnum\pdfoutput>0
    \examn@engine=1
  \else
    % this _is_ pdftex, but it's in generate-dvi mode
    % (we decide not to detect this case with the other engines)
    \examn@engine=0
  \fi
\fi
%    \end{macrocode}
%
% \subsubsection{Fonts}
%
% Choose the font set, based on |\if@psfonts| and |\examn@mtselect|.
% The following is \emph{messy}, and it's not clear to me if it's
% irreducibly so, or whether I'm just doing it the wrong way.
%
% Case |\examn@mtselect| is 0: the rather hacky \Lpackage{mathptm} solution.
%    \begin{macrocode}
\def\ex@fontlabel{???}
\if@psfonts
  \ifcase\examn@mtselect
    \def\ex@fontlabel{mathptm}
    \ifexamn@serif
      \RequirePackage{times}
    \else
      \RequirePackage{helvet}
    \fi
    \RequirePackage{mathptm}
    \ClassWarningNoLine{exam-n}{Using mathptm fonts}
%    \end{macrocode}
%
% Case |\examn@mtselect| is 1 or 2: use mathtime or Mathtime Pro 2 fonts
% for maths.  We use postscript Times and Helvetica for the body fonts
% in both cases.
%    \begin{macrocode}
  \or
    \def\ex@fontlabel{mathtime}
    \RequirePackage[LY1]{fontenc}   % specify text font encoding
    \RequirePackage[LY1,mtbold]{mathtime}   % switch math fonts
    \ifexamn@serif
      \RequirePackage{times}
    \else
      \RequirePackage{helvet}
    \fi
    \ClassWarningNoLine{exam-n}{Using Mathtime fonts}
  \or % use mtpro2 fonts
    \def\ex@fontlabel{mtpro2}
    \RequirePackage[T1]{fontenc}
    \RequirePackage{textcomp}
    \ifexamn@serif
      \renewcommand\rmdefault{ptm} % the default
    \else
      \RequirePackage[scaled=0.9]{helvet}
      \renewcommand\rmdefault{phv}
    \fi
    \RequirePackage[mtpbb]{mtpro2}
    \ClassWarningNoLine{exam-n}{Using MTPro2 fonts}
%    \end{macrocode}
%
% Finally, case |\examn@mtselect| is 3: use STIX2 fonts: \url{http://www.stixfonts.org}.
% Since this requires fontspec, it also requires either XeLaTeX or
% LuaLaTeX.  If we are in this branch, and not using either
% engine, then fail with what we hope is a reasonably clear error.
%
% First off, refuse to work with original TeX.
%    \begin{macrocode}
  \or
    \def\ex@fontlabel{stix2}
    \ifcase\examn@engine
      \ClassError{exam-n}
        {You can't use STIX fonts with original/DVI LaTeX}
        {You must use either XeLaTeX or LuaLaTeX}
%    \end{macrocode}
%
% Use of the STIX fonts with pdflatex mostly works, but there is a
% tricky current/legacy issue here.
% The \Lpackage{stix2} package is intended to use the STIX2
% fonts with `legacy' \TeX\ engines.  Does this apply to pdflatex, now
% it defaults to unicode input?  See the discussion of
% \Lpackage{unicode-math} below.
%
% As of TeXLive 2022, this mostly works, in the sense that we do use STIX
% fonts, but the upright-pi support below fails (no LaTeX errors, but
% |\uppi| produces slanted pi).
%    \begin{macrocode}
    \or % pdflatex
      \RequirePackage{stix2}
%    \end{macrocode}
%
% We support only Xe\TeX\ and Lua\TeX\ here, since only these can use
% `system' fonts.  For Xe\LaTeX\ we use `system' Helvetica and Courier
% fonts (slightly scaled) as the sans and mono fonts, respectively, for the sake of
% completeness.
%
% Note: unicode-math is a little complicated.  As I (unfortunately)
% discovered via mistaken bug report
% \url{https://github.com/stipub/stixfonts/issues/235},
% the \Lpackage{stix} package is intended to be used \emph{only} for
% `legacy' \TeX\ engines, and \Lpackage{unicode-math} for current ones
% such as Xe\LaTeX\ and Lua\LaTeX.
% I'm fairly confident (as of 2022 July 11) that the following does
% the right thing, but not yet 100% confident.
%
% Note that (as explained in the \Lpackage{unicode-math} manual, we
% should use the STIX Two \emph{Math} font for symbols, and not the
% text font.
%    \begin{macrocode}
    \or % XeLaTeX
      \RequirePackage[bold-style=ISO,math-style=ISO]{unicode-math}
      \setmathfont{STIX Two Math}
      \setmainfont{STIX Two Text}
    \or % LuaLaTeX: like XeLaTeX
      \RequirePackage[bold-style=ISO,math-style=ISO]{unicode-math}
      \setmathfont{STIX Two Math}
      \setmainfont{STIX Two Text}
    \fi
%    \end{macrocode}
% The no-match case shouldn't happen.
%    \begin{macrocode}
  \else
    \def\ex@fontlabel{ERROR}
    \ClassError{exam-n}
      {Impossible value of mtselect: \examn@mtselect}
      {This shouldn't happen -- this is a class file bug}
  \fi
%    \end{macrocode}
%
% There are no font complications when using CM fonts.  That's nice.
%    \begin{macrocode}
\else
  \def\ex@fontlabel{CM}
  \ClassWarningNoLine{exam-n}{Using CM fonts}
\fi
%    \end{macrocode}
%
% Report what engine and font configuration we're using.
%    \begin{macrocode}
\typeout{Environment:
  engine: \ifcase\examn@engine original/DVI\or pdfTeX\or XeTeX\or LuaTeX\else ???\fi;
  fonts: \ex@fontlabel;
  options: % show any non-default options
  \ifexamn@uprightpi uprightpi, \fi
  \ifexamn@siunitx siunitx, \fi
  \ifexamn@serif\else noserif, \fi
  \if@pageperquestion pageperquestion, \fi
  \if@perquestionmarks\else noperquestionmarks, \fi
  \if@showmarktotals\else noshowmarktotals, \fi
  \if@twosidepages twoside, \fi
  \if@fleqn fleqn, \fi
  \iffussydescription\else sloppydescription, \fi
  \ifbigfont hugefont, \fi
  \if@showsolutions showsolutions\else noshowsolutions\fi}
%    \end{macrocode}
%
% If we're using a sans serif font, then redefine |\normalfont| appropriately.
% The macro |\examn@bodyfontchange| stores up these font changes until
% they're applied just after |\maketitle|.
%    \begin{macrocode}
\def\examn@bodyfontchange{}
\ifexamn@serif \else
  \ClassWarningNoLine{exam-n}{Using sans serif fonts}
  \DeclareRobustCommand\normalfont
    {\usefont\encodingdefault\sfdefault\seriesdefault\shapedefault \relax}
\fi
%    \end{macrocode}
% And similarly for the case where we want large fonts.
% This (as it turns out) requires changing only |\normalsize| and not
% |\normalfont|, so the two are in principle compatible; however we
% implement both of them by redefining |\examn@bodyfontchange|, so
% they're not in practice (a future fix, perhaps).
%    \begin{macrocode}
\ifcase\examn@fontvariant
  % default: do nothing
  \def\examn@bodyfontchange{
    % ...apart from redefine \small to be more clearly distinct from \normalsize
    \renewcommand\small{%
      \@setfontsize\normalsize{9}{11}%
      \abovedisplayskip 9\p@ \@plus1.5\p@ \@minus5\p@
      \abovedisplayshortskip \z@ \@plus2.5\p@
      \belowdisplayshortskip 5\p@ \@plus2.5\p@ \@minus2.5\p@
      \belowdisplayskip \abovedisplayskip}}
\or
  % font variant 1: 18pt
  \def\examn@bodyfontchange{
    \renewcommand\normalsize{%
      \@setfontsize\normalsize{18}{24}%
      \abovedisplayskip 18\p@ \@plus3.5\p@ \@minus9\p@
      \abovedisplayshortskip \z@ \@plus5\p@
      \belowdisplayshortskip 10\p@ \@plus5\p@ \@minus5\p@
      \belowdisplayskip \abovedisplayskip
      \let\@listi\@listI}
    \renewcommand\small{%
      \@setfontsize\normalsize{12}{16}%
      \abovedisplayskip 12\p@ \@plus2\p@ \@minus6\p@
      \abovedisplayshortskip \z@ \@plus4\p@
      \belowdisplayshortskip 6.5\p@ \@plus3\p@ \@minus3\p@
      \belowdisplayskip \abovedisplayskip}
    \parindent=24pt
    \parskip=18pt
    % Redefine \FormatPartMarks so that it doesn't push the text off the paper
    \let\FormatPartMarks\examn@variantFormatPartMarks
  }
\or
  % font variant 2: 36pt
  \def\examn@bodyfontchange{
    \renewcommand\normalsize{%
      \@setfontsize\normalsize{36}{42}%
      \abovedisplayskip 36\p@ \@plus7\p@ \@minus17.5\p@
      \abovedisplayshortskip \z@ \@plus10.5\p@
      \belowdisplayshortskip 21\p@ \@plus10.5\p@ \@minus10.5\p@
      \belowdisplayskip \abovedisplayskip
      \let\@listi\@listI}
    \renewcommand\small{%
      \@setfontsize\normalsize{24}{28}%
      \abovedisplayskip 24\p@ \@plus5\p@ \@minus12\p@
      \abovedisplayshortskip \z@ \@plus8\p@
      \belowdisplayshortskip 14\p@ \@plus8\p@ \@minus8\p@
      \belowdisplayskip \abovedisplayskip}
    \parindent=48pt
    \parskip=36pt
    % Redefine \FormatPartMarks so that it doesn't push the text off the paper
    \let\FormatPartMarks\examn@variantFormatPartMarks
  }
\else
  % Bad font variant
  \ClassError{exam-n}
    {Bad font variant \examn@fontvariant}
    {I didn't expect to see that number (broken style file re largefont/hugefont?)}
\fi
%    \end{macrocode}
% The above font variants require a |\FormatPartMarks| variant which
% avoids being pushed off the edge of the page.
%    \begin{macrocode}
\def\examn@variantFormatPartMarks#1{%
  \setbox0=\hbox{\hskip 1em \textbf{[#1]}}%
  \@tempdima=0.8\marginsize
  \ifdim\wd0>\@tempdima
    \advance\@tempdima -\wd0
    \hbox to 0pt{\hskip\@tempdima \box0\hss}%
  \else
    \hbox to 0pt{\box0\hss}%
  \fi}
%    \end{macrocode}
%
% Adjust maths font sizes for the various cases:
%    \begin{macrocode}
\DeclareMathSizes\@xiipt{12}{9}{7}
\DeclareMathSizes\@xipt{10}{8}{6}
%    \end{macrocode}
%
% \subsubsection{PDF metadata, and other document identifiers}
%
% Generate an identifier, |\examn@docident| for this paper.  This is obtained
% from the university or school course code, followed by the
% day-of-year, and the number of minutes since midnight (the goal here
% is to produce an identifier which automatically increments in time,
% but which isn't obviously a date.
%
% Yes, a big |\ifcase| would be more straightforward;
% no, that wouldn't be any fun at all
% (also it ends up looking messy and even tricksier).
%    \begin{macrocode}
\def\examn@setdocident{%
  \begingroup
    \def\@step##1##2\@nil{\advance\@tempcnta##1 \def\@tempa{##2}}
    \def\@tempa{{31}{28}{31}{30}{31}{30}{31}{31}{30}{31}{30}{31}}%
    \@tempcnta=\day             % day of month
    \@tempcntb=\month           % month of year (unit-offset)
    \loop
      \advance\@tempcntb-1
      \ifnum \@tempcntb>0
        \expandafter\@step\@tempa\@nil
    \repeat
    \@tempcntb=\year            % yes, do calculate leap years
    \divide\@tempcntb 4 \multiply\@tempcntb 4
    \ifnum\@tempcntb=\year
      \ifnum\month>2            % but let's not worry about century years...
        \advance\@tempcnta 1
      \fi
    \fi
    % remove any \\ or ~ in the coursecode fields
    \let\\\space
    \let~\space
    \xdef\examn@docident{% first element is based on uni/school course code
      \ifx\@coursetitle\@empty
        \ifx\@schoolcoursecode\@empty
          exam%
        \else
          \@schoolcoursecode
        \fi
      \else
        \@coursetitle
      \fi
      /\the\@tempcnta           % day-of-year
      -\the\time}               % minutes since midnight
  \endgroup
}
%    \end{macrocode}
%
% Add information to the PDF document metadata.
%    \begin{macrocode}
\ifcase\examn@engine
  \let\@SetDocumentInfo\relax % original TeX
\or % pdfTeX
  \def\@SetDocumentInfo{\pdfinfo{/Title (\examn@docident)}}%
  % Don't put out an /Author(xxx) info entry -- there may be
  % multiple authors, and it isn't obviously useful
\or % XeTeX
  % dvipdfm special -- see the dvipdfm manual
  \def\@SetDocumentInfo{\special{pdf: docinfo << /Title (\examn@docident) >>}}%
\or % LuaTeX
  % from the LuaTeX manual
  \def\@SetDocumentInfo{\pdfextension info {/Title (\examn@docident)}}%
\fi
\AtBeginDocument{\examn@setdocident\@SetDocumentInfo}
%    \end{macrocode}
%
% \subsubsection{Exam metadata}
%
%    \begin{macrocode}
\def\@exambanner{}
\def\exambanner{\def\@exambanner}

\def\@schoolcoursecode{}
\def\schoolcoursecode{\def\@schoolcoursecode}

\def\@universitycoursecode{}
\def\universitycoursecode{\def\@universitycoursecode}

\def\@paperident{}
\def\paperident{\def\@paperident}

\def\@examdate{}
\def\examdate{\def\@examdate}

\def\@examtime{}
\def\examtime{\def\@examtime}

\def\@coursetitle{}
\def\coursetitle{\def\@coursetitle}
%    \end{macrocode}
% Display the degree descriptions, which are separated by |\\|.  Put
% each one in an |\hbox|, so it doesn't break over the line.
%    \begin{macrocode}
\def\@degreedescriptions{}
\def\degreedescriptions{\def\@degreedescriptions}
\def\@displaydegreedescriptions{%
  \let\@tempb\leavevmode
  \def\dd##1\\{%
    \def\@tempa{##1}%
    \ifx\@tempa\@empty
      \let\next\relax
    \else
      \@tempb\hbox{##1}\let\next\dd
    \fi
    \def\@tempb{\discretionary{}{}{\kern0.5em--\kern0.5em}}%
    \next}
  \expandafter\dd\@degreedescriptions\\}
%    \end{macrocode}
%
% We can optionally check the total number of questions.  Store this
% if it is present, and add a check to the |\end{document}| to check
% it at the end if it was indeed set at the beginning.  Command
% |\CheckTotalQuestions| is added to |\AtEndDocument| below.
%    \begin{macrocode}
\def\@numquestions{}
\def\numquestions{\def\@numquestions}
\def\CheckTotalQuestions{%
  \ifnum\@draftstatus < 2
    \ifx\@numquestions\@empty \else
      \ifnum\c@questionnumber=\@numquestions \else
        \ClassWarning{exam-n}
          {Expected \@numquestions\space questions, got \thequestionnumber!}
        \ifnum\@draftstatus > 0 % draft mode
          \begin{center}
            \textbf{\highlighted{Expected \@numquestions\space questions, got \thequestionnumber}}
          \end{center}
        \fi
      \fi
    \fi
  \fi
}
%    \end{macrocode}
%
%
% \subsection{Geometry and colours}
%
% Adjust the spacing for article and amsmath flush-left equations.
% Amsmath doesn't use |\mathindent| in the same way \LaTeX\ does, and
% this semi-workaround may break with early versions of amsmath.  See
% the amsmath FAQ at http://www.ams.org/tex/amsmath-faq.html for
% some discussion.
%    \begin{macrocode}
\if@fleqn
  \mathindent\parindent
  \@mathmargin=\parindent
\fi
%    \end{macrocode}
%
% |\marginsize| is the size of the margin all round.  Users shouldn't
% change this in normal circumstances, but are free to if they have
% some particular reason.  Note that if all you want to do is move the
% text to one side for printing reasons, use |\nudgeleft|.
%    \begin{macrocode}
\newdimen\marginsize
  \marginsize=35mm

\headheight=15pt
\headsep=15pt
%    \end{macrocode}
%
% It's useful to colour-code material that's present in the compose
% and draft modes but which won't appear in the final version; this
% partly reassures question authors that this is `meta' material.
%    \begin{macrocode}
\definecolor{meta}{rgb}{0.7,0.2,0.2}
\def\highlighted{\textcolor{meta}}
%    \end{macrocode}
% We (currently) want solutions to appear as coloured blocks.  The
% colour is this one:
%    \begin{macrocode}
\definecolor{solutiontext}{rgb}{0.2,0.2,0.5}
%    \end{macrocode}
% And finally a colour for `discreet' information, such as identifier
% numbers.
%    \begin{macrocode}
\definecolor{discreettext}{rgb}{0.6,0.6,0.6}
%    \end{macrocode}
%
% Set up the textblock in |\@settextblock|.
% The argument is the amount by which the text block is to be nudged
% to the left.
%    \begin{macrocode}
\newcommand\@settextblock[1]{
  \textwidth=\paperwidth
    \advance\textwidth -2\marginsize
  \textheight=\paperheight
    \advance\textheight -2\marginsize
  \oddsidemargin=\marginsize
    \advance\oddsidemargin -1in
    \advance\oddsidemargin -#1
  \evensidemargin=\oddsidemargin
  \topmargin=\marginsize
    \advance\topmargin -\headheight
    \advance\topmargin -\headsep
    \advance\topmargin -1in
  \marginparwidth=\marginsize
    \advance\marginparwidth -1.5cm
    \advance\marginparwidth #1
%%     \typeout{paperwidth=\the\paperwidth, paperheight=\the\paperheight,
%%     textwidth=\the\textwidth, textheight=\the\textheight,
%%     oddsidemargin=\the\oddsidemargin,
%%     headheight=\the\headheight, headsep=\the\headsep, topmargin=\the\topmargin}
  \marginparsep=0.5cm
}
%    \end{macrocode}
% In the \Lopt{draft} case, we nudge the text block to the side, to
% give a larger margin.
%    \begin{macrocode}
\ifnum\@draftstatus > 0
  \@settextblock{2cm}
\else
  \@settextblock{0pt}
\fi
%    \end{macrocode}
% |\leftnudge| is the amount by which the textblock is shifted
% leftwards.  This is usually zero, but is given a non-zero value in
% draft modes, to give space for marginal comments, and may be given a
% non-zero value by users, in the preamble, if that is required for
% some reason by some limitation of the subsequent printing process.
% It may be negative, to nudge the block rightwards.
%    \begin{macrocode}
\let\leftnudge\@settextblock
%    \end{macrocode}
%
% Format the marginal paragraphs (ie, comments)
%    \begin{macrocode}
\renewcommand\@marginparreset{%
  \reset@font
  \@setminipage
  \raggedright
  \small
}
%    \end{macrocode}
%
% Add a few other formatting parameters.
%
% Note that the (default) layout of |\FormatPartNumber| depends on a
% non-zero |\parindent|, so if the latter is changed, the former must
% be, too.  In fact, if |\parindent| is zero or otherwise small,
% \begin{quotation}
% \catcode`\|=0
% |begingroup |ttfamily
% \catcode`\{=12 \catcode`\}=12 \catcode`\\=12
% |noindent \newcommand\FormatPartNumber{|linebreak
% |noindent|null|quad\hbox to 2em{(\StylePartNumber{partnumber})\hss}}
% |endgroup
% \end{quotation}
% works adequately as a part number,
% though this does result in paragraphs being a little hard to make
% out, unless there's a really generous |\parskip|.
%    \begin{macrocode}
\setlength{\parindent}{2em}
\setlength{\parskip}{\bigskipamount}
%    \end{macrocode}
%
% We must clear out any floats at the end of the paper, without
% forcing a new page (figures and tables don't float, but there are
% other packages which can generate floats, such as the
% \Lenv{sidewaystable} from the \Lpackage{rotating} package).
% This technique is simplified form Donald Arsenau's \Lpackage{placeins} package.
%    \begin{macrocode}
\def\examn@flushfloats{\par
  \begingroup
    \edef\@tempa{\@deferlist\@dbldeferlist}
    \ifx\@tempa\@empty \else
      \clearpage
    \fi
  \endgroup
}
%    \end{macrocode}
% Text at the end of the paper.  Command |\ClosingText| is added to
% |\AtEndDocument|, below.
%    \begin{macrocode}
\ifcase\@draftstatus % Final version
  \def\ClosingText{
    \examn@flushfloats
    \begin{center}\textbf{End of Paper}\\\end{center}
    \mark{END}}
\or % Draft version
  \def\ClosingText{
    \examn@flushfloats
    \begin{center}\textbf{End of Draft Paper}\\\end{center}
    \mark{END}}
\else % Compose version (nothing, because this would be on a page by itself)
  \def\ClosingText{
    \examn@flushfloats
    \mark{END}}
\fi
%    \end{macrocode}
%
% \subsection{Headings and marks}
%
% The headers and footers include continuation information.
%    \begin{macrocode}
\RequirePackage{fancyhdr}
\pagestyle{fancy}
\setlength{\headwidth}{\textwidth}
\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}
\fancyhead{}
\fancyfoot{}
%    \end{macrocode}
% Include an identifier in the footer, unless an identifier is present
% in |\@paperident|.
%    \begin{macrocode}
\fancyfoot[L]{{\tiny\textcolor{discreettext}{%
  \ifx\@paperident\@empty\examn@docident\else\@paperident\fi
}}}
%    \end{macrocode}
% We use marks to determine whether, at the top of the page, we're
% continuing a question or starting a new one.  Set |\mark{n}| at the
% beginning of a question, and |\mark{}| at the end.  In principle, if
% |\topmark| is non-empty, then we're currently in the given question,
% and if it's empty, we're not.  Now, the \LaTeX\ floats mechanism
% (which is involved in the handling of marginpars as well as floats)
% interferes with this because it can call the output routine other
% than at the end of a page.  Thus |\topmark| is essentially useless
% within \LaTeX, if there's any change of a float appearing.
%
% However, we can work around this by setting |\examn@topmark| in the
% page footer, to be the value of |\botmark| there.  I think this has
% exactly the same semantics as |\topmark|, possibly apart from some
% pathological situations.
%
% So, for the footer, we include a continuation mark if and only if
% |\examn@topmark| is non-empty.  We additionally store |\botmark| into |\examn@topmark|.
%    \begin{macrocode}
\fancyfoot[R]{%
  \def\@tempa{END}
  \xdef\examn@topmark{\botmark}
  \ifx\examn@topmark\@empty
    \formatcontinuations{Paper continued over\dots}%
  \else\ifx\examn@topmark\@tempa
    \formatcontinuations{END}
  \else
    \formatcontinuations{Q\,\examn@topmark\ continued over\dots}%
  \fi\fi
}
\fancyfoot[C]{\thepage/\pageref{lastpage}}
%    \end{macrocode}
% In the header, we perform essentially the same test, using the
% |\examn@topmark| we saved in the previous page's footer.
%    \begin{macrocode}
\def\examn@topmark{}
\ifnum\@draftstatus=0
  \fancyhead[L]{%
    \ifx\examn@topmark\@empty \else
      \formatcontinuations{Q\,\examn@topmark\ continued}%
    \fi
  }
\fi
%    \end{macrocode}
% We use the header to shout out the status of the paper, in
% particular making it very clear if we're showing the exam answers:
% we don't want this version to be accidentally distributed at the exam\dots.
% The |\examn@bighead| macro sets its contents in a large box, but
% without making the header any larger -- we want the headheight in
% drafts to be the same as in the final version (because otherwise
% we'd get different page breaks).
%    \begin{macrocode}
\def\examn@bighead#1{\strut\vbox to 0pt{\vss\hbox{\examn@header@shoutformat{#1}}\vskip 10mm}}
\ifnum\@draftstatus = 1
  \if@showsolutions
   \fancyhead[C]{\examn@bighead{\highlighted{DRAFT + SOLUTIONS, p\thepage/\pageref{lastpage}}}}
  \else
   \fancyhead[C]{\examn@bighead{\highlighted{DRAFT, p\thepage/\pageref{lastpage}}}}
  \fi
\else
  \if@showsolutions
    % Add a very prominent banner
    \fancyhead[C]{\examn@bighead{\highlighted{SHOWING SOLUTIONS}}}
  \fi
\fi
%    \end{macrocode}
%
% Allow \texttt{.clo} files to override the formatting of the various
% continuation markers.
%    \begin{macrocode}
\def\formatcontinuations#1{\textbf{#1}}
%    \end{macrocode}
%
% Now define a command which writes out the page number of the last
% page.  This is added to |\AtEndDocument|, in the correct order, below.
%    \begin{macrocode}
\def\WriteLastPageLabel{\label{lastpage}}
%    \end{macrocode}
%
% \subsubsection{The title page}
%
% Define a special page style for the title page.
%
% There is no header: all of the text on the page is handled by |\maketitle|
% The first-page footer doesn't show anything, but it does have to set
% |\examn@topmark| in case Q1 starts on this page.
%    \begin{macrocode}
\def\ps@titlepage{
  \def\@oddhead{}
  \def\@oddfoot{\xdef\examn@topmark{\botmark}}
}
%    \end{macrocode}
%
% Create a custom maketitle.
% Check all required information is present.
%    \begin{macrocode}
\def\RequiredMetadata#1#2#3{
  \expandafter\ifx\csname @#1\endcsname\@empty
    \ClassError{exam-n}{#2}{#3 (command \@backslashchar #1)}
  \else
    \typeout{#1 check OK}
  \fi}
%    \end{macrocode}
% Define a |\CheckExamMetadata| test, but only if the macro wasn't defined in a |.clo| file.
%    \begin{macrocode}
\@ifundefined{CheckExamMetadata}{
  \def\CheckExamMetadata{
    % First, data which is always required
    \RequiredMetadata{examdate}
          {No exam date given}
          {Specify an exam date}
    \RequiredMetadata{examtime}
          {No exam time given}
          {Specify an exam time}
    \RequiredMetadata{exambanner}
          {No exam banner given}
          {Specify an exam banner (eg Examination for the degree...)}
    \iffussydescription
      % The following tests can be skipped by using the option [sloppydescription]
      \RequiredMetadata{universitycoursecode}
          {No paper title given}
          {Specify a university course code (eg PHYS3031)}
      \RequiredMetadata{coursetitle}
          {No course title given}
          {Specify a course title (eg Quantum Mechanics)}
      \RequiredMetadata{degreedescriptions}
          {No paper subject given}
          {Specify a 'degree description' (eg Physics 3)}
      \RequiredMetadata{rubric}
          {No rubric given}
          {Specify a rubric, or declare its absence with \protect\norubric}
    \fi
  }}{}
%    \end{macrocode}
% Start the |\maketitle| command.
% First, handle the 'final' or 'draft' versions.
%    \begin{macrocode}
\renewcommand\maketitle{
  \ifnum\@draftstatus < 2       % final or draft version
    \CheckExamMetadata
%    \end{macrocode}
% All OK so far\dots.  Now produce the actual text.
%    \begin{macrocode}
    \thispagestyle{titlepage}
    \begin{center}
      \null
      \vskip -1.5cm
%    \end{macrocode}
% Firse produce headers at the top, which highlight things which make
% the paper non-distributable (eg, it includes the answers!).
% Only highlight the number of shouts when we're not showing
% solutions.  The highlights above indicate clearly that the
% paper is not in its distributable format; the purpose of
% this output here is to highlight that the paper is still not
% distributable, \emph{even though} it's not showing solutions.
%    \begin{macrocode}
      \if@showsolutions
        \nointerlineskip
        \vbox to 0pt{\vss
          \examn@header@shoutformat{\shout{SHOWING SOLUTIONS}}
          \vskip 1.5\bigskipamount}
      \else
        \ifnum\examn@shoutcounttotal>0
          \typeout{SHOUTS: \the\examn@shoutcounttotal}
          \nointerlineskip
          \vbox to 0pt{\vss
            \examn@header@shoutformat
              {\highlighted{SHOUTS: \the\examn@shoutcounttotal\ (see end)}}
            \vskip 1.5\bigskipamount}
        \fi
      \fi
      \nointerlineskip
%    \end{macrocode}
% The logo, in a zero-size box.
%    \begin{macrocode}
      \hbox to \textwidth{% date and time
        \vbox to 0pt{\vskip-2ex \UniLogo{50mm}\vss}
        \hss
%    \end{macrocode}
% Make the |\@examtime| box have zero depth, or else fancyhead
% complains that the size of the header isn't big enough, and
% ups it for the whole document.  In this position, it's OK that
% it juts out of the bottom of the header line.
%    \begin{macrocode}
        \setbox0=\hbox{\vtop{% \vtop or \vbox here?
          % Opinions differ:
          % This week, Norman prefers \vtop because it gives a cleaner top line.
          \hsize=0.5\textwidth
          \leftskip=0pt plus1fil \rightskip=0pt \parfillskip=0pt
          \baselineskip=2.5ex
          \parskip=0.25ex
          \let\\\par
            \ifx\@examdate\@empty
              \shout{missing exam date}
            \else
              \@examdate
            \fi
            \par
            \ifx\@examtime\@empty
              \shout{missing exam time}
            \else
              \@examtime
            \fi
            \par}}
        \dp0=0pt
        \box0}
      \vskip4\bigskipamount
      %\UoGname\\[\medskipamount]
      {\uppercase\expandafter{\@exambanner}}\\[\medskipamount]
      \vbox{}\hrule
      \ifx\@degreedescriptions\@empty\else
        \@displaydegreedescriptions\\
      \fi
%    \end{macrocode}
% Exam identification.  The |\@coursetitle| is the most important
% item, so make that biggest.
% Adjust the size of the course title so that it fits on to one line
% (though if |\Large| is still too big, then we give up and go to multiple lines).
%    \begin{macrocode}
      \vskip 2\baselineskip plus 0.3fil
      \def\@tempa{\def\@tempa{\vskip 0.5\baselineskip}}
      \ifx\@schoolcoursecode\@empty\else
        \@tempa
        {\large\textbf{\@schoolcoursecode}}
      \fi
      \ifx\@universitycoursecode\@empty\else
        \@tempa
        {\large\textbf{[~\@universitycoursecode~]}}
      \fi
      \ifx\@coursetitle\@empty\else
        \setbox0=\hbox{\Huge\textbf{\@coursetitle}}
        \ifdim\wd0>\columnwidth
          \setbox0=\hbox{\LARGE\textbf{\@coursetitle}}
          \ifdim\wd0>\columnwidth
            % we're not going any smaller than this
            \setbox0=\vbox{\hsize\columnwidth
              \Large\bfseries
              \@coursetitle}
          \fi
        \fi
        \vskip 1.2\ht0          % generous vertical skip, size-dependent
        \ifhbox0
          \hbox to \columnwidth{\hss\box0\hss}
        \else
          \box0
        \fi
      \fi
%    \end{macrocode}
% Rubric(s).  The macros |\@empty| and |\@nnil| both have an empty
% expansion.  The difference between them is that |\@rubric| is set to
% |\@nnil| by |\norubric| to indicate that |\@rubric| is deliberately
% empty, whereas if |\@rubric| is |\@empty|, that's trapped in the
% checks above as an error.
%    \begin{macrocode}
      \vskip 2\baselineskip plus 0.3fil
      \parindent=0pt
      \parskip=0.5\baselineskip
      \ifnum\examn@fontvariant > 0
        % Don't put the rubric here (see below)
        {\LARGE Rubric: see overleaf}
      \else
        \ifx\@rubric\@empty\else
          \ifx\@rubric\@nnil\else
            % If there's a rubric, separate from the base rubric, then
            % separate the two with an hrule (the per-exam rubric
            % presumably represents special instructions for this exam,
            % so should be highlighted)
            \vbox{\let\emph\textbf
              \@rubric
              \par}
            \vskip2\baselineskip
            \hrule
            \vskip1.5\baselineskip
          \fi
        \fi
%    \end{macrocode}
% Let the base rubric be a justified block of text near the bottom.
%    \begin{macrocode}
        \ifx\@baserubric\@empty \else
          \@baserubric \par
        \fi
      \fi % end \ifbigfont \else ...
    \end{center}
%    \end{macrocode}
% These various fractions of fil glue don't add up as I'd expect
% them to.  No matter: the fractions here produce some spreading
% out of the rubrics below the titles, which is what I'm after.
%    \begin{macrocode}
    \vskip 2\baselineskip plus 0.6fil % \newpage is {\vfil\penalty-\@M}
    \vbox to 0pt{\hbox to \textwidth{%
        \tiny
        \textcolor{discreettext}
          {\hfil\ifx\@paperident\@empty\examn@docident\else\@paperident\fi\hfil}}\vss}
    \penalty -\@M
    \@displayconstants
%    \end{macrocode}
% The compose version is nice and simple, because we don't have to do
% any checks.  FIXME: Hmm: this is largely redundant, because we don't
% document, and so don't really support, including the metadata in the
% [compose] mode preamble.  However we clearly did include this as one
% point: was that just out of whim, or was there a requirement for that?
%    \begin{macrocode}
  \else % compose version
   \begin{tabular}{rl}
      \textbf{Exam}&
        {\def\\{ / }\@schoolcoursecode}\\
      \textbf{Course codes}&
        \@universitycoursecode\\
      %% \textbf{Subject}&
      %%   {\def\and{and}\begin{tabular}
      %% {\@degreedescriptionstemplate}\@degreedescriptions
      %% \end{tabular}}\\
      \textbf{Date \& time}&
        {\def\\{, }\@examdate, \@examtime}\\
    \end{tabular}
  \fi
%    \end{macrocode}
% And chatter about what decision we've made.
%    \begin{macrocode}
  \ifcase\@draftstatus
    % Final version
    \typeout{Exam \@schoolcoursecode: FINAL VERSION}
  \or % Draft version
    \typeout{Exam \@schoolcoursecode: DRAFT VERSION}
  \else % Compose version
    \typeout{Exam \@schoolcoursecode: COMPOSE VERSION}
  \fi
  %
  \examn@bodyfontchange
  \normalfont\normalsize
  \ifnum\examn@fontvariant>0
    % Put the rubric on a second page, in the 'huge' size.
    \begin{center}
      \parskip=18pt
      \let\emph\textbf \@rubric\par
      \vskip\baselineskip
      \hrule
      \vskip\baselineskip
      \ifx\@baserubric\@empty \else
        \@baserubric \par
      \fi
    \end{center}
    \newpage
  \fi
}
%    \end{macrocode}
%
% \subsection{Structuring commands}
%
% \subsubsection{Sections}
%
% Define simple sectioning commands.  We also check that these aren't
% inside questions.
%    \begin{macrocode}
\setcounter{secnumdepth}{0}
%    \end{macrocode}
% Redefine |\section|, to include a check that it's not being called
% within a question (|\@currentquestion| is defined only inside the
% \Lenv{question} or \Lenv{mcq} environments).
%    \begin{macrocode}
\renewcommand\section{
  \@ifundefined{@currentquestion}\@@section
    {\ClassError{exam-n}{Misplaced section}
      {You can't have a section inside a question;\MessageBreak
        move it before the {question} environment starts}}}
\newcommand\@@section{\@startsection{section}{1}{\z@}%
                        {-3.5ex \@plus -1ex \@minus -.2ex}%
                        {1ex \@plus.1ex \@minus 0.5ex}%
                        {\fmt@section}}
\def\fmt@section#1{%
  \examn@prequestionspace{}
  \hbox to \textwidth{{\hfil\bfseries SECTION #1\hfil}}%
}
%    \end{macrocode}
% Redefine |\subsection| similarly.
%    \begin{macrocode}
\renewcommand\subsection{
  \@ifundefined{@currentquestion}\@@subsection
    {\ClassError{exam-n}{Misplaced subsection}
      {You can't have a subsection inside a question;\MessageBreak
        move it before the {question} environment starts}}}
\newcommand\@@subsection{\@startsection{subsection}{2}{\z@}
                         {-2ex \@plus -3ex \@minus -0.2ex}
                         {0.5ex \@plus .1ex \@minus 0.1ex}
                         {\fmt@subsection}}
\def\fmt@subsection#1{%
  \examn@prequestionspace{}
  \noindent\textbf{#1}}
%    \end{macrocode}
% We must redefine the section and subsection mark commands to gobble
% their arguments.  If we don't, then \LaTeX\ gets \emph{terribly}
% confused about what the mark is.  I don't quite follow what happens
% in this case, but symptoms include Babel blowing up, and
% \TeX\ running out of stack space.  So: bad.
%    \begin{macrocode}
\let\sectionmark\@gobble
\let\subsectionmark\@gobble
%    \end{macrocode}
%
% Just to be safe, we should also disable the other sectioning
% commands.
%    \begin{macrocode}
\def\@badsection#1#2{\ClassError{guexam}{Bad section}
  {The exam class goes not support subdivisions like #1{#2}}}
\def\subsubsection{\@badsection{subsubsection}}
\def\paragraph{\@badsection{paragraph}}
\def\subparagraph{\@badsection{subparagraph}}
%    \end{macrocode}
%
% The above redefinitions break the |\tableofcontents| macro.
% It's unlikely but \emph{possibly} useful, in some cases, to have a
% table of contents in an exam paper.  Whether or not it is, we should
% avoid breaking it, on a principle of least surprise.  The following
% makes the macro work again, even though it's not particularly
% pretty.
%    \begin{macrocode}
\renewcommand\tableofcontents{\bigskip
  \hbox to \textwidth{\hfil\textbf{\Large Contents}\hfil}%
  \@starttoc{toc}}
%    \end{macrocode}
%
% \subsubsection{Questions and solutions}
% Counters:
%    \begin{macrocode}
\newcount\marktotal           % number of marks accumulated so far
\newcount\markgoal            % number of marks we should have in the end
\newcounter{questionnumber}
\setcounter{questionnumber}0
%    \end{macrocode}
%
% Counter partnumber holds the number (i,ii,iii, etc) of the parts
% within a question.  It's a \LaTeX\ counter, so we can use |\roman|.
%
% We override the \Lenv{article} |\part| command.
%
% FIXME:
% We would like to use |\StylePartNumber| here, but can't, because
% that's defined as being eg |\alph|, and not |\@alph|.  To change
% this, we'll have to retire |\StylePartNumber|, in favour of saying
% that, to change the formatting here, it's merely necessary to
% redefine |\thepartnumber|.
%    \begin{macrocode}
\newcounter{partnumber}
\renewcommand\thepartnumber{\thequestionnumber\@alph\c@partnumber}
\renewcommand\part[1][]{%
  \if@nobreak \else
    \par
    \@nobreakfalse
  \fi
  \ifvmode
    \vskip 0pt plus 4\bigskipamount
    \penalty-50
  \fi
  \def\@tempa{#1}%
  \ifx\@tempa\@empty
    \refstepcounter{partnumber}%
    \noindent\FormatPartNumber
  \else
    \noindent\FormatPartNumber[#1]%
  \fi
}
%    \end{macrocode}
% The default |\FormatPartNumber| creates a box the same size as a
% parindent.  This therefore assumes that it's following a |\noindent|.
%    \begin{macrocode}
\newcommand\FormatPartNumber[1][]{%
  \def\@tempa{#1}%
  \hbox to \parindent{(%
      \ifx\@tempa\@empty
        \StylePartNumber{partnumber}%
      \else
        \@tempa
      \fi
    )\hss}%
}
%    \end{macrocode}
% And by default we use alphanumeric counters for parts (we abstract
% this, rather than simply including |\alph| in the definition of
% |\FormatPartNumber|, so that we use the same style for the
% `answerpartnumber' counter.
%    \begin{macrocode}
\let\StylePartNumber\alph
%    \end{macrocode}
%
% A flag indicating whether we should start a new page before the next
% question.  This is manipulated by both |\section| and |\question|.
%    \begin{macrocode}
\newif\if@newpagebeforequestion
\if@pageperquestion
  \@newpagebeforequestiontrue
\else
  \@newpagebeforequestionfalse
\fi
%    \end{macrocode}
%
% The command |\examn@prequestionspace| is called just before we start a
% new question, or before we start a header which precedes a
% question.  It adds some vertical space, given in the argument,
% unless the |@pageperquestion| settings imply that this should be a
% newpage instead, in which case the vertical space here is ignored.
%    \begin{macrocode}
\def\examn@prequestionspace#1{%
  \if@pageperquestion
    \if@newpagebeforequestion
      % Add all the stretchability here, rather than stretching out
      % displays and lists above this on the page.
      \newpage
      % Clear the \@newpagebeforequestion flag, to suppress the action
      % of any following calls to \examn@prequestionspace, until the end
      % of the next question.
      \global\@newpagebeforequestionfalse
    \fi
  \else
    #1%
  \fi
}
%    \end{macrocode}
%
% Macro |\examn@endquestion| gathers here a couple of checks shared
% between end-of-question macros (see the \Lenv{mcq} environment and
% the |\endquestion| macro).
% The argument to the |\examn@endquestion| macro is material (such as the
% mark-total) which should go at the end of the question,
% and be surrounded by various spacing and resetting actions.
%    \begin{macrocode}
\long\def\examn@endquestion#1{%
  \mark{}         % the position of this call is slightly sensitive (but this works)
  \if@pageperquestion
    \global\@newpagebeforequestiontrue
  \fi
  #1
  \@nobreakfalse
  \everypar{}
}
%    \end{macrocode}
%
% \subsubsection{Partmarks}
%
% |\partmarks| is used at the end of a paragraph to indicate the
% number of marks associated with this part.  The starred variant
% |\partmarks*| is used only when the end of a part is the end of a display
% maths block which doesn't have an equation number.  This moves the
% part note up a bit, which looks nicer.
%
% It's also permissible to use |\partmarks| in the solution, to
% indicate precisely where marks accrue.  It's reasonable for this to
% be more fine-grained than in the question.  We don't check that the
% partmarks in the solution add up to the mark goal.
%
% Manage the partmarks comments as the contents of a zero-width hbox,
% which is sized to fit reasonably well in the margin.  We insert this
% into the output just before formatting the partmarks.
%
% The |\defaultpartmarkscategory| macro creates a default partmarks
% `category'.  If this is something like |{category?}|, then this
% should prompt question authors to indicate the category in each call
% to |\partmarks|.  This can be declared within a |.clo| option file
% (and is declared above, so that it can be read from there without error).
%
% Below, we must add the footnote text after the end of the paragraph,
% otherwise this inserts vertical mode material, which causes a
% linebreak, at least in the case where the last line is almost full.
% Because we are using the hook mechanism, this package now depends on
% the expl3 modules, and thus on TeXLive versions which aren't too old
% (how old is too old?  I'm not sure, but I expect TeXLive 2020 is new enough).
%    \begin{macrocode}
\newbox\examn@partmarkscomment
\def\examn@makepartmarkscomment#1{%
  \setbox0=\hbox{\small #1}%
  \ifdim\wd0 < 3\marginparwidth % let shortish comments wrap here
    \setbox\examn@partmarkscomment=\hbox to 0pt{\hbox{%
        \vtop to 0pt{%
          \hsize=\marginparwidth
          \parindent=0pt
          \parskip=0pt
          \leftskip=1em         % 1em matches the hskip in default \FormatPartMarks
          \rightskip=0pt plus 0.5\marginsize
          \hangindent=2em \hangafter=-1
          \small
          #1\vss}}\hss
    }%
  \else
    \stepcounter\@mpfn
    \protected@xdef\@thefnmark{\thempfn}%
    \@footnotetext{#1}%
    % 3em matches the \leftskip+\hangindent above
    \setbox\examn@partmarkscomment=\hbox to 0pt{%
      \hskip3em\highlighted{\small [comment \thempfn]}\hss}%
  \fi
  }
\def\examn@getpartmarkscomment{%
  \ifhbox\examn@partmarkscomment
    \box\examn@partmarkscomment
  \fi}
%    \end{macrocode}
% Now, finally, define the actual |\partmarks| command.
%    \begin{macrocode}
\def\partmarks{%
  \@ifstar{\@tempswatrue \@partmarks}{\@tempswafalse \@partmarks}}
\newdimen\@partmarksspace
  \@partmarksspace=2em % default value
%    \end{macrocode}
% Check whether there's an optional (comment/category) argument,
% enclosed in |[...]|.
%    \begin{macrocode}
\def\@partmarks{%
  \@ifnextchar[%]
    \@@partmarks{\@@partmarks[]}}
%    \end{macrocode}
% Implement the part marks indicator.  First, check that
% `perquestionmarks' is turned on; if it's not, then we shouldn't be
% using |\partmarks|.
%    \begin{macrocode}
\def\@@partmarks[#1]#2{%
  \if@perquestionmarks
    \if@insolution
      \@@partmarks@solution{#1}{#2}%
    \else
      \@@partmarks@question{#1}{#2}%
    \fi
  \else
    \ClassError{exam-n}{\string\partmarks\ is not compatible with
      noperquestionmarks}{Either remove \string\partmarks\ or remove
      the noperquestionmarks option}
  \fi
}
%    \end{macrocode}
%
% Finally, implement the two partmarks variants for questions and solutions.
%
% The |\@@partmarks@endenv| command is called when |\partmarks| is
% invoked within an environment, and is used to add a suitable vbox to
% an after-environment hook.
%
% First prepare the vbox that's to be inserted, and then work out how
% to place it.  The |\vskip\baselineskip| in the |\@partmarksbox| is
% to better position the box relative to where it ends up in the
% vertical list, and the value has a large heuristic element.
%    \begin{macrocode}
\newbox\@partmarksbox
\def\@@partmarks@endenv@display{\@tempswatrue\@@partmarks@endenv@common}
\def\@@partmarks@endenv@nodisplay{\@tempswafalse\@@partmarks@endenv@common}
\def\@@partmarks@endenv@common#1{%
  \ifvbox\@partmarksbox % ooops -- been here before: two \partmarks in one env
    \ClassError{exam-n}
               {Two partmarks commands in one environment! First one IGNORED!}
               {You can (currently) have only one partmarks command per environment}
  \fi
  \global\setbox\@partmarksbox=\vbox to 0pt{\vss
    \hbox to \textwidth{%
      \strut\hfill
      \examn@getpartmarkscomment
      \FormatPartMarks{#1}}%
    \vskip\baselineskip}%
  %\dp\@partmarksbox=0pt
%    \end{macrocode}
% Test whether we have the |{question}| environment as our immediate
% container, as opposed to being in an inner environment.
%    \begin{macrocode}
  \def\@tempa{question}%
  \ifx\@tempa\@currenvir
    \setbox1=\vbox to 0pt{\vss\box\@partmarksbox}%
    \ifvmode
      \box1
    \else
      \vadjust{\box1}%
    \fi
  \else
%    \end{macrocode}
% Generally the \cmd|env/<env>/end| hook seems to
% produce better results, in terms of positioning things at the end of
% environments, but this does not work for environments
% where the command is located inside a display (ie, in \TeX\ terms,
% inside |$$...$$|); in these situations we have to use the
% \texttt{.../after} hook instead.  Such displays are most typically amsmath
% alignment environments, but an \cmd|\halign| inside a display will
% also qualify (see the discussion of `alignment displays' in \TeX
% Book ch.19).  There isn't a completely straightforward way of
% detecting this situation (though amsmath's \cmd|\start@align| sets
% \cmd|\xatlevel@| to be non-\cmd|\@empty|, which we take to indicate the
% amsmath case), so we have to rely on the caller of this
% command to invoke the \texttt{...@display} or \texttt{...@nodisplay}
% variant appropriately.
%    \begin{macrocode}
    \if@tempswa % display variant
      \AddToHookNext{env/\@currenvir/after}{%
        %\typeout{hook:endenv/display #1}%
        \ifvmode\box\@partmarksbox
        \else\vadjust{\box\@partmarksbox}\fi}%
    \else
      \AddToHookNext{env/\@currenvir/end}{%
        %\typeout{hook:endenv/nodisplay: env/\@currenvir/end #1}%
        \ifvmode\box\@partmarksbox
        \else\vadjust{\box\@partmarksbox}\fi}%
    \fi
  \fi
}
%    \end{macrocode}
%
% First, define the questions version, for appearing in the version candidates see.
% Here, \cmd|#1| is the possibly empty `classification' text, and \cmd|#2| is the
% number of marks.  At this point |\if@tempswa| is true if we got here
% via the \cmd|\partmarks*| variant, and false if it's the unstarred one.
%
% The argument |#2| must be a number: any non-number text will not
% cause an error but will appear in the text.
%
% But first\dots!
%
% The |\partmarks| command increments a global counter, and we
% \emph{don't} want to do this when an \Lpackage{amsmath} alignment is evaluating
% the content in its `measuring' phase.  Fortunately,
% \Lpackage{amsmath} has an (internal) flag |\ifmeasuring@| which is
% true in that phase, which it uses for this purpose, so make this macro a no-op in that case.
%    \begin{macrocode}
\def\@@partmarks@question{%
  \ifmeasuring@
    \let\@@partmarksnext\@gobbletwo
  \else
    \let\@@partmarksnext\@@partmarks@question@do
  \fi
  \@@partmarksnext
}
%    \end{macrocode}
% On with the main business.
%    \begin{macrocode}
\def\@@partmarks@question@do#1#2{%
  \global\advance\marktotal #2
  \let\@@partmarksnext\relax % base case
%    \end{macrocode}
% Display the `part category', \emph{visible in the question},
% if \Lopt{showsolutions} is true, either
% explicitly, or implicitly as a consequence of the
% compose/draft/final mode.  It's arguable that this should be
% dependent on the mode only, but after some discussion, it ended up
% seeming more reasonable to tie this to \Lopt{showsolutions} directly.
%    \begin{macrocode}
  \if@showsolutions
    \def\@tempa{#1}%
    \ifx\@tempa\@empty
      \ifx\examn@defaultpartmarkscategory\relax
        \let\examn@category\relax
      \else
        \examn@makepartmarkscomment{\highlighted{\examn@defaultpartmarkscategory}}%
      \fi
    \else
      \examn@makepartmarkscomment{\highlighted{#1}}%
    \fi
  \fi
%    \end{macrocode}
%
% If |\@tempswa|, then this is the starred form of |\partmarks|.
% This is intended to be used only occasionally, after a display or
% list environment, where for some reason the command can't go inside
% the environment.
%    \begin{macrocode}
  \if@tempswa
    \ifdim\displaywidth>0pt
      \ClassError{exam-n}
                 {Don't use \partmarks* inside a display}
                 {Use \partmarks inside the display, or \partmarks*
                   after it, if necessary}
%    \end{macrocode}
% Else we are most likely just after an equation or just after a list
% environment, or something similar.
% (here and below we include some |{#2:n}| debugging code for when I,
% inevitably, revisit this to worry about the spacing).
%    \begin{macrocode}
    \else
      \@@partmarks@endenv@nodisplay{#2}%{#2:1*}%
    \fi
%    \end{macrocode}
% We've called the unstarred version of |\partmarks|.
% This is the more usual mode.
%    \begin{macrocode}
  \else
    \ifdim\displaywidth>0pt
%    \end{macrocode}
% We're in a display, after |$$|: \TeX\ is probably (but not certainly) in
% maths mode just now; if we're in an amsmath alignment, we're in
% specifically inner maths mode; there are other, rarer, ways of being
% in an `alignment display'.  Additionally, and commonly, if we're in
% an \Lenv{equation} environment now -- which we can detect because
% that, amongst other amsmath environments, sets |\eqnsw| to be true
% -- then we're \emph{not} in an alignment, but we \emph{are} in a
% case where the |\eqno| technique will fail (with `You can't use
% `eqno' in math mode.'), so catch that.
%
% CONSIDER: is this |\@eqnsw| test in fact the only one I have to do
% -- is the inner math mode test equivalent?  That is, is this, when
% it comes down to it, testing the actual thing I need to test here?
% This will require another dive into the amsmath magic.
%    \begin{macrocode}
      \@tempswafalse
      \ifmmode\ifinner \else \@tempswatrue \fi\fi
      \if@tempswa
        \if@eqnsw % not so fast... we're in an {equation}
          \@tempswafalse
        \fi
      \fi
      \if@tempswa
%    \end{macrocode}
% We're in outer maths mode, which we can take to mean a |\[...\]| equation.
% In this case, we can very neatly position the partmarks indicator
% using |\eqno|.
%    \begin{macrocode}
        \def\@@partmarksnext{\eqno \hbox to 1sp{% the \eqno argument must not be zero size
            \examn@getpartmarkscomment
            \FormatPartMarks{#2}%{#2:1}
            \hss}}%
%    \end{macrocode}
% Or we're in one or other type of display.
%    \begin{macrocode}
      \else
        \def\@@partmarksnext{\@@partmarks@endenv@display{#2}}%
        %\def\@@partmarksnext{\@@partmarks@endenv@display{#2:2,\@currenvir}}%
      \fi
%    \end{macrocode}
%
% Otherwise, |\displaywidth=0pt|, and we're not in a display.
% If we are in the |{question}| environment, as opposed to any sub-environment,
% we end the paragraph here and put the partmarks indicator at the end
% of the final line of the paragraph (this technique is filched from the TeXBook, p106).
% Otherwise, we add a suitable box to an end-of-environment hook.
%
% Omitting the |{question}| test below, and handling all cases with
% the end-of-paragraph technique, works in most case, in the sense of
% looking fine.  Where it fails is in the case of, eg, |{quote}|,
% where the end-of-line ends up indented from the right.
%
% Using the hook has the additional advantage that |\partmarks| can be anywhere
% within the environment and this locates it at the end.
%
% The dimension |\@partmarksspace| controls how much space the
% partmarks-number takes up, the default is the special case of 0pt,
% which puts it in the margin.
%    \begin{macrocode}
    \else
      \def\@tempa{question}%
      \ifx\@tempa\@currenvir
        \ifdim\@partmarksspace > 0pt
         {\unskip\nobreak\hfil\penalty50 \hskip\@partmarksspace
            \hbox{}\nobreak\hfil\examn@getpartmarkscomment\FormatPartMarks{#2}%{#2:3}%
          \parfillskip=0pt \finalhyphendemerits=0 \par}
        \else
          \unskip\nobreak\hfill\examn@getpartmarkscomment\FormatPartMarks{#2}\par%{#2:4}\par
        \fi
        \let\@@partmarksnext\relax
      \else
        \def\@@partmarksnext{\@@partmarks@endenv@nodisplay{#2}}%
        %\def\@@partmarksnext{\@@partmarks@endenv@nodisplay{#2:5,\@currenvir}}%
      \fi
    \fi
  \fi
%    \end{macrocode}
%
% The `question' variant of this macro includes an |\ignorespaces| at the
% end, since that is generally the right thing to do (the command
% almost always appears at the end of paragraphs, or after equations).
%    \begin{macrocode}
  \@@partmarksnext
  \ignorespaces
}
%    \end{macrocode}
% Then the solutions version, for the benefit of markers, which is
% typically more finely itemized, and which isn't summed (ie, we don't
% at present confirm that the marks here match the question's marks goal).
% The solutions variant of this macro omits the |\ignorespaces|
% (since in solutions this macro is scattered within the text).
% Setting |\dp0=0pt| is probably unnecessary, but guarantees that box0
% has zero depth, so no extra vertical space appears because of
% this new box.
%    \begin{macrocode}
\def\@@partmarks@solution#1#2{%
  \setbox0=\vbox to 0pt{\vss
    \hbox to \textwidth{\hfil\hbox to 0pt{\quad\small[\dots #2]\hss}}
    \vskip0.25ex }%
  \dp0=0pt
  \ifvmode
    \box0
  \else
    \vadjust{\nointerlineskip\box0}%
  \fi
}
%    \end{macrocode}
%
% The code above permits page-breaks between lists and |\partmarks|.
% That's because |\@endparenv|, which is called within |\endtrivlist|,
% includes a negative |\@endparpenalty|.  Override that here.  This
% applies to the whole document, but that's OK, since we want to
% discourage inconvenient page-breaks generally.
%    \begin{macrocode}
\@endparpenalty=\@M
%    \end{macrocode}
%
% The number of marks is formatted by the command |\FormatPartMarks|, which
% may be overridden, using |\renewcommand| in a |.clo| file.
% In this default case, |\FormatPartMarks| goes into the margin, so we
% don't need to keep space for it, so set |\@partmarksspace| to zero.
%    \begin{macrocode}
\newcommand\FormatPartMarks[1]{\hbox to 0pt{\hskip1em \textbf{[#1]}\hss}}
\@partmarksspace=\z@
%    \end{macrocode}
%
% \subsubsection{The question environments: normal questions}
%
% The \Lenv{question} environment.  Implement
% this using with a |\question| macro, rather than using
% |\newenvironment|, so that we can define an optional argument.
%    \begin{macrocode}
\newcommand\question{%
  \if@perquestionmarks
    \let\ex@next\@questionmarks
  \else
    \let\ex@next\@questionnomarks
  \fi
  \@ifnextchar[%]
    {\ex@next}{\ex@next[]}}
%    \end{macrocode}
% Switch between the perquestionmarks and noperquestionmarks cases.
%    \begin{macrocode}
\def\@questionmarks[#1]#2{%
  \def\@tempa{#2}% marks available for this question
  \ifx\@tempa\@empty
    \ClassError{exam-n}
      {Missing mark goal for question (using 0 instead)}
      {Missing mark goal for question (using 0 instead)}
    \def\@tempa{0}
  \fi
  \ifx\@includequestionoverridenumber\@empty
    \do@question{#1}{\@tempa}%
  \else
    \ClassWarning{exam-n}{Forcing question number
      \@includequestionoverridenumber, in included question #2}
    \do@question{\@includequestionoverridenumber}{\@tempa}%
  \fi
}
\def\@questionnomarks[#1]{%
  \do@question{#1}{0}%
}
%    \end{macrocode}
%
% \subsubsection{The question environments: multiple-choice questions}
%
% And finally multiple-choice questions.  The \Lenv{mcq} environment
% contains a list of possible answers, numbered from one up, including
% precisely one correct answer, indicated by |\answer|.  These are
% laid out in a compact itemized list.  We do not indicate the number
% of marks, since these are always the same.
%
% First, counters:
% \begin{itemize}
%  \item |\ex@nmcq| is the number of answers which MCQs can have.  If
%  this is less than 1, it's a flag that MCQs haven't been enabled by
%  |\multiplechoiceanswers|.
%  \item |\ex@mcqi| is the running index of answers.
%  \item |\ex@mcqnanswer| is the number of correct answers found
%  (which is checked to be one, at the end).
% \end{itemize}
%    \begin{macrocode}
\newcount\ex@nmcq
\ex@nmcq=-1
\newcount\ex@mcqnanswer
\def\multiplechoiceanswers#1{\ex@nmcq=#1}
%    \end{macrocode}
% The \Lenv{mcq} environment takes a single argument indicating the
% correct answer.  The environment starts with the text question,
% followed by a number of |\item| answers.
%    \begin{macrocode}
\newenvironment{mcq}
   {\parindent=0pt
    \ifnum\ex@nmcq<1
      \ClassError{exam-n}
        {mcq environment without preceding multiplechoiceanswers declaration}
        {The mcq environment may only be used if the number of
          permitted MCQ answers has been declared with \string\multiplechoiceanswers}
    \else
%    \end{macrocode}
% Declare |\item| for the individual answers, and |\answer| for the
% single correct answer.
%    \begin{macrocode}
      \def\item{\@tempswafalse\ex@mcqitem}
      \def\answer{\@tempswatrue\ex@mcqitem}
%    \end{macrocode}
% Initialise counters, and invoke the common |\do@question| macro.
%    \begin{macrocode}
      \ex@mcqi=0
      \ex@mcqnanswer=0
      \do@question{}{1}
    \fi}
%    \end{macrocode}
% At the end of the \Lenv{mcq} environment, check that we found
% |\ex@nmcq| answers, and that the count of correct answers,
% |\ex@nmcqanswer|, is exactly one.
%    \begin{macrocode}
   {\par
    \ifnum\ex@mcqi<\ex@nmcq
      \ClassWarning{exam-n}{Too few potential answers in MCQ \thequestionnumber}
      \@shout{Too few potential answers in MCQ \thequestionnumber}
      \ifnum\@draftstatus > 0
        \highlighted{TOO FEW ANSWERS}\par
      \fi
    \fi
    \ifcase\ex@mcqnanswer
      \ClassWarning{exam-n}
        {No correct MCQ answer provided in question \thequestionnumber}
      \@shout{No correct MCQ answer provided in question \thequestionnumber}
      \ifnum\@draftstatus > 0
        \highlighted{NO CORRECT ANSWER PROVIDED}\par
      \fi
    \or
       % ex@mcqanswer=1: correct -- do nothing
    \else
      \ClassWarning{exam-n}
        {Too many correct MCQ answers provided in question \thequestionnumber}
      \@shout{Too many correct MCQ answers provided in question \thequestionnumber}
      \ifnum\@draftstatus > 0
        \highlighted{TOO MANY CORRECT ANSWERS}\par
      \fi
    \fi
%    \end{macrocode}
% Other end-question tidyups (compare |\endquestion|).
%    \begin{macrocode}
    \examn@endquestion{\relax}
   }
%    \end{macrocode}
% Each |\item| within the environment (implemented by |\ex@mcqitem|)
% creates a new paragraph.
%    \begin{macrocode}
\newcount\ex@mcqi
\def\ex@mcqitem{%
  \par
  \ifnum\ex@mcqi=0
    % first one
    \smallskip
    \parskip=0pt   % nothing fancy -- we assume these won't spread
                   % over more than one line
    \advance\leftskip by 2em
  \fi
  \advance\ex@mcqi by 1
  \noindent
  \if@tempswa
    % the correct answer
    \advance\ex@mcqnanswer 1
    \if@showsolutions
      \hbox to 0pt{\hss \highlighted{$\Longrightarrow$ \@Alph\ex@mcqi . }}%
    \else
      \hbox to 0pt{\hss \@Alph\ex@mcqi . }%
    \fi
  \else
    \hbox to 0pt{\hss \@Alph\ex@mcqi . }%
  \fi
}
%    \end{macrocode}
%
% \subsubsection{The question environments: the common handler}
%
% The common question handler.  This is the macro which does the work.
% Argument |#1| is the overriding question number (empty indicates the
% next one in sequence); argument |#2| is the mark goal, which must be
% non-zero.
%    \begin{macrocode}
\def\do@question#1#2{%
  \par % get that out of the way...
  \markgoal=#2
  \marktotal=0
  \ifx\examn@questionpreamble\@empty
  \else
    \vspace{2\baselineskip}
    \hbox to \textwidth{\hfil\textbf{\examn@questionpreamble}\hfil}
    \questionpreamble{}
  \fi
  \setcounter{partnumber}{0}
  \setcounter{answerpartnumber}{0}
%    \end{macrocode}
% If the argument |#1| is non-empty, then it is a number, forcing the
% question number.  This is local, however -- don't use it to change
% the sequence of questions, so don't set the `questionnumber'
% counter, but only the current label.
%    \begin{macrocode}
  \refstepcounter{questionnumber}
  \def\@tempa{#1}
  \ifx\@tempa\@empty \else
    \edef\@currentlabel{#1}
  \fi
%    \end{macrocode}
%
% If |pageperquestion| is true, then start a new page here (unless
% this is the first question).
%    \begin{macrocode}
  \examn@prequestionspace{%
    \if@nobreak
      % after a heading (or something like that)
    \else
      % we're not forcing a new page here, but this would be a good point to choose
      \vskip 2\baselineskip plus 8\baselineskip
      \penalty-200
    \fi
  }
%    \end{macrocode}
%
% The optional argument specifies a question number.  In compose mode,
% this unequivocally specifies the question number -- end of story.
% In the two other modes, this is expected to match the question
% number implied by the count of questions so far, and we check this,
% and warn if it is not so.
%    \begin{macrocode}
  \if@questionnumberchecks
    \def\@tempa{#1}% intended question number
%    \end{macrocode}
% If there's no optional argument, we've got nothing to do
%    \begin{macrocode}
    \ifx\@tempa\@empty
      % no optional argument -- easy
      \def\@currentquestion{\thequestionnumber}
%    \end{macrocode}
%
% We have a non-null optional argument in |#1|.
% Check the question number in the argument.  If there's a
% mismatch, warn in draft mode, and fail in final mode.  First,
% however, check that the argument |#1| is just a number (if it's not,
% the author should have disabled this check in the preamble, and we
% shouldn't be here at all).  We do that check by setting a counter
% inside a box.  If |#1| is all number, then this will result in a
% zero-width box; if not, then there will be unparsed characters and a
% non-zero-width box (nifty, eh?).
%    \begin{macrocode}
    \else
      \setbox0=\hbox{\@tempcnta=#1}
      \ifdim\wd0>0pt
        \ClassWarning{exam-n}{Non-numeric question number, #1.
          You probably want to put \string\QuestionNumberChecksOff in the preamble}
        \par\textbf{Non-numeric question number, #1.
          You probably want to put \hbox{$\backslash$\ttfamily QuestionNumberChecksOff} in the preamble}
          (the formatting below may be messed up).\par
      \fi
%    \end{macrocode}
% Switch on the draft status: in the final version, this mismatch is an error
%    \begin{macrocode}
      \ifcase\@draftstatus
        % Final version
        \@tempcnta=#1
        \ifnum\c@questionnumber=\@tempcnta
          \def\@currentquestion{#1}
        \else
          \ifx\@includequestionoverridenumber\@empty
            \ClassError{exam-n}
              {\string\question[#1] is actually question \thequestionnumber!}
              {The question in {question} environment number
                \thequestionnumber\space is specified as
                \string\question[#1].\MessageBreak
               This is an error in 'final' mode.\MessageBreak
               Perhaps you need \string\QuestionNumberChecksOff?}
            \def\@currentquestion{???}
          \else
            \ClassWarning{exam-n}{Forcing question number \@includequestionoverridenumber,
              in {question} environment number \thequestionnumber}
            \edef\@currentquestion{\@includequestionoverridenumber}% this doesn't seem to expand in fact!
            \message{current question=\@currentquestion, override \@includequestionoverridenumber}
          \fi
        \fi
%    \end{macrocode}
% In the other two modes, we simply need a warning.
%    \begin{macrocode}
      \or
        % Draft version -- let the given number override
        % \the\questionnumber, but warn if there's a difference.
        \@tempcnta=#1
        \ifnum\c@questionnumber=\@tempcnta \else
          \ClassWarning{exam-n}
            {\string\question[#1] is actually question \thequestionnumber!}
        \fi
        \def\@currentquestion{#1}
      \else
        % compose mode -- argument overrides without question
        \def\@currentquestion{#1}
      \fi
    \fi
  \else
    % skip question-number checks
    \def\@tempa{#1}% intended question number
    \ifx\@tempa\@empty
      % no optional argument -- this is possibly an error, so warn
      \ClassWarning{exam-n}{\string\QuestionNumberChecksOff\ is in
        force, but this question has no [number]}
      \def\@currentquestion{\thequestionnumber}
    \else
      \typeout{Forcing question \thequestionnumber\space to be #1}
      \def\@currentquestion{#1}
    \fi
  \fi
%    \end{macrocode}
% Format the question number, first removing and discarding any parindent
% (the reason we don't just start with |\noindent| here is because
% there may be a blank line between the |\begin{question}|, and the
% text, so we'd (inadvertently) start another new paragraph when the
% actual question starts).
% The call to |\mark| should come \emph{after} setting the
% question number: if it happens before, and there is a page-break
% immediately before the new question, we can get a spurious
% `Q?? continued' on the previous page.
%
% If a paragraph starts inside a level of grouping -- for example
% |{\bf 1} text...| or even just |{T}ext| -- then the |\everypar|
% tokens are expanded inside that group, which means that the
% resetting of |\everypar| is local, with the result that the tokens
% are reused for the next paragraph.  Make the emptying of |\everypar|
% global for that reason.
%    \begin{macrocode}
  \everypar{\setbox0=\lastbox % discard \box0
    \FormatQuestionNumber
    \mark{\@currentquestion}%
    \global\everypar{}}
}
%    \end{macrocode}
% Format the question number.  This command is documented as existing,
% so that it can be potentially overridden in a \texttt{.clo} file.
%    \begin{macrocode}
\newcommand\FormatQuestionNumber
  {\hbox to 0pt{\hss \textbf{\@currentquestion}\hskip1em}}
%    \end{macrocode}
%
% Finish off the question:
% Format the indication of the total number
% of marks, and do a few consistency checks.
%    \begin{macrocode}
\def\endquestion{%
  \ifnum\marktotal=\markgoal
    \typeout{Question \@currentquestion\if@perquestionmarks, \the\marktotal\space marks\fi}
    \iffalse % all of this is redundant, and ends up too shouty
    \ifcase\@draftstatus
      % Final version -- do nothing
      \relax
    \or % draft version
      \relax                    % no, the above is too much; do nothing
    \else % compose version
      \par
      \hfil\textbf{\highlighted{[Q\,\@currentquestion\if@perquestionmarks, \the\marktotal\space marks\fi]}}%
        \break
    \fi
    \fi
%    \end{macrocode}
% In the case where the mark total doesn't match, make a noise about it.
%    \begin{macrocode}
  \else
    \ClassWarning{exam-n}
      {Question \@currentquestion\space has a total of \the\marktotal\space marks,
        \MessageBreak
        when it should have \the\markgoal}
    \begin{center}
      \edef\@tempa{Question \@currentquestion\space
        has a total of \the\marktotal\space marks,
        when it should have \the\markgoal}
      \expandafter\shout\expandafter{\@tempa}
    \end{center}
  \fi
%    \end{macrocode}
% Make a few tidyups in the end-question wrapper.
%    \begin{macrocode}
  \examn@endquestion{%
    \if@showmarktotals
      \par                      % into vertical mode
      \nobreak                  % keep the marks total with the question
      \vbox to 2\baselineskip{
        \vss
        % this should be very similar to the call to
        % \FormatPartMarks in \@partmarks, above
        \hbox to \textwidth{\strut\hfill\FormatPartMarks{Total: \the\markgoal
          \ifnum\@draftstatus>0
            % in draft modes, put a fairly discreet confirmation in the total
            \space
            \highlighted{\ifnum\marktotal=\markgoal OK\else X\fi}%
          \fi}}}
    \fi
  }
}
%    \end{macrocode}
%
% \subsubsection{Other structures}
%
% The \Lenv{questiondata} environment allows the author to provide
% some additional data or equations for the question.
% This environment ends a preceding paragraph.
%    \begin{macrocode}
\newenvironment{questiondata}{%
  \par
  \penalty50 % poor break
  \vbox\bgroup
    \slshape
    \parindent=0pt \parskip=\medskipamount
    \smallskip
    \hrule
    \nobreak
    \smallskip
    \noindent \ignorespaces
}{%
    \par
    \nobreak
    \medskip
    \hrule width \textwidth
    \par
  \egroup % end of \vbox
}
%    \end{macrocode}
%
% If |\questionpreamble| is called some time before the start of a
% \Lenv{question} environment, then its contents will be printed at
% the start of the next question.
%    \begin{macrocode}
\newcommand\questionpreamble[1]{\gdef\examn@questionpreamble{#1}}
\let\examn@questionpreamble\@empty
%    \end{macrocode}
%
% In those cases where the sequence of question numbers is not
% supposed to match the sequence of question environments, declare
% that we should turn off the corresponding checks within |\question|.
%    \begin{macrocode}
\newif\if@questionnumberchecks
\@questionnumbercheckstrue
\newcommand\QuestionNumberChecksOff{\@questionnumberchecksfalse}
%    \end{macrocode}
%
% The underlying style (article) has enumerate and itemize
% environments which have a rather generous amount of space.  This
% makes sense in an article, but within an exam, which already has a
% lot of white space around, such lists end up looking unattractively
% ragged.  So redefine them slightly here, adjusting the spacing
% appropriately.  First `enumerate'\dots
%    \begin{macrocode}
\def\enumerate{%
  \ifnum \@enumdepth >\thr@@\@toodeep\else
    \advance\@enumdepth\@ne
    \edef\@enumctr{enum\romannumeral\the\@enumdepth}%
      \expandafter
      \list
        \csname label\@enumctr\endcsname
        {\usecounter\@enumctr
          \topsep0pt
          \partopsep0pt
          %\parskip=5.0pt \parsep=\parskip
          \def\makelabel##1{\hss\llap{##1}}}%
  \fi}
%    \end{macrocode}
% \dots then `itemize'.
%    \begin{macrocode}
\def\itemize{%
  \ifnum \@itemdepth >\thr@@\@toodeep\else
    \advance\@itemdepth\@ne
    \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}%
    \expandafter
    \list
      \csname\@itemitem\endcsname
      {\topsep0pt
        \partopsep0pt
        \def\makelabel##1{\hss\llap{##1}}}%
  \fi}
%    \end{macrocode}
% To match the format of the question number above, we have to make
% sure that the enumerate environment's counters are different.
%    \begin{macrocode}
\renewcommand\theenumi{\@roman\c@enumi}
%    \end{macrocode}
%
% \subsection{Other useful commands}
%
% |\comment| creates a marginal comment in non-final modes.  There is an
% interaction with the marks mechanism -- see the discussion about
% |\topmark| above.
%    \begin{macrocode}
\newcommand\comment[1]{%
  \ifnum\@draftstatus > 0
    \marginpar{\highlighted{#1}}%
    % should we \@shout this, too?
  \fi
  \ignorespaces
}
%    \end{macrocode}
%
% The |\author| command is a convenience.  Used within a
% \Lenv{question} environment, it creates a comment with the author's
% name.  I may expand its functionality in future.
%    \begin{macrocode}
\renewcommand\author[1]{\comment{Author: #1}}
%    \end{macrocode}
%
% The |\@shout| macro is intended for use in all modes: it appends a
% remark to a list of exclamations which are highlighted at the end of
% the document.
% The argument to |\@shout| can have expandable things (such as
% |\thequestionnumber|) in it.
% Shouts appear in all modes and cannot be suppressed.
%    \begin{macrocode}
\newtoks\@allshouts \@allshouts={}
\def\@shout#1{\edef\@tempa{#1}\expandafter\@@shout\expandafter{\@tempa}}
\def\@@shout#1{\global\@allshouts=\expandafter{\the\@allshouts\t{#1}}}
\def\showthe@shouts{%
  {\def\t##1{{\LARGE\noindent\highlighted{NOTE: ##1}\par}}%
    \the\@allshouts}%
  % Remark on the number of shouts in the aux file
  {\@tempcnta=0 \def\t##1{\advance\@tempcnta1}\the\@allshouts
    \protected@write\@auxout{}%
      {\string\examn@shoutcount{\the\@tempcnta}}}}
%    \end{macrocode}
% Define the user macro |\shout|
%    \begin{macrocode}
\def\shout#1{\textbf{\highlighted{#1}}\@shout{#1}}
%    \end{macrocode}
% Take note of the number of shouts, and write this information to the
% \texttt{.aux} file, so that it can be read in next time.
%    \begin{macrocode}
\newcount\examn@shoutcounttotal
\examn@shoutcounttotal=0
\def\examn@shoutcount#1{\global\examn@shoutcounttotal=#1}
%    \end{macrocode}
%
% The |\includequestion| command includes a question from another
% file.  For convenience, we disable
%|\documentclass|, |\usepackage|, |\RequirePackage|, and the
% \Lenv{document} environment, so that the included file may be a
% complete \LaTeX\ document.
% We don't try too hard to support including just any old \LaTeX, here:
% any complicated preamble requirements in an included file should
% probably be managed by the exams convener transplanting them into
% the preamble of the main document.  This may be an overly
% simple-minded approach, and may change in future versions.
%    \begin{macrocode}
\def\dummy@documentclass{%
  \@ifnextchar[\dummy@@documentclass{\dummy@@documentclass[]}}
\def\dummy@@documentclass[#1]#2{}
\def\includequestion{
  \@ifnextchar[%]
    {\@includequestion}{\@includequestion[]}}
\def\@includequestion[#1]#2{%
  \begingroup
    \let\documentclass\dummy@documentclass
    \let\document\@empty % not \relax: makes \begin think {document} is undef'd
    \let\enddocument\endinput % stop reading, discarding any junk below \end{document}
    \def\@tempa{#1}
    \ifx\@tempa\@empty \else
      \def\@includequestionoverridenumber{#1}
      \message{includequestion override: \@includequestionoverridenumber}
    \fi
    \def\usepackage##1{\ClassWarning{exam-n}
      {Ignoring \string\usepackage{##1} in included question #2}}
    \let\RequirePackage\usepackage
    \input{#2}
  \endgroup
}
\let\@includequestionoverridenumber\@empty
%    \end{macrocode}
%
% \subsection{The solution environment}
%
% The solution environment is made somewhat complicated by the way we
% implement it.  Rather than using a verbatim-like technique to omit
% the source lines (as done successfully by, for example, the
% \Lpackage{comments} package) we set the contents of the environment
% in a box, which we throw away.  This technique is more robust in
% principle, but it does mean we have to disable some things which
% have global side-effects.
%
% Maintain a flag which indicates whether we're in a solution
% environment or not.
%    \begin{macrocode}
\newif\if@insolution
\@insolutionfalse
%    \end{macrocode}
%
% We want to use |\part| within solutions.  If we were to do so naively
% however, we would end up incrementing the |partnumber| counter
% which that macro uses, which either disturbs the numbering of the
% parts in the question (if the solutions are interspersed in the
% question) or starts out of sequence (if the solutions are at the
% end).  So we maintain a separate counter.  Additionally, we want to
% force the formatting of the solution parts, to be independent of the
% formatting in the main question
%    \begin{macrocode}
\newcounter{answerpartnumber}
\newcommand{\examn@solutionpart}{%
  \par
  \stepcounter{answerpartnumber}
  \noindent\hbox to \parindent{(\StylePartNumber{answerpartnumber})\hss}}
%    \end{macrocode}
%
% Specify how solutions should be shown.  The following makes them
% ragged right, slightly smaller and slanted, with rules fore and aft.
% This doesn't leap out, but the difference should be detectable.
% Putting a box round the solution would be desirable (it keeps it all
% together and would allow a coloured background), but that's rather
% hard to arrange in practice.
%
% Solutions are shown in a slightly smaller size (namely |\small|).
% It's debatable whether this is a good thing or not.  Note that if
% this is changed by removing the |\small|, then
% |\examn@dummycaptions| will have to be adjusted, too.
%
% If either of the `enlarged font' options has been given, then we set
% the solutions in the same large font, since these might be
% distributed to students as model answers.
%    \begin{macrocode}
\def\@formatsolution{\par
  \if@insolution
    \ClassError{exam-n}{Misplaced solution}{You can't have a solution within a solution}
  \else
    \@insolutiontrue            % this happens within a group
  \fi
  \examn@dummycaptions          % dummy captions within solutions
  \typeout{SHOWING SOLUTIONS}
  \let\part\examn@solutionpart
%    \end{macrocode}
% Checks done; now get on with the layout
%    \begin{macrocode}
  \vskip 1ex plus 2\bigskipamount % add stretchable space...
  \penalty-\@lowpenalty         % ...and encouragement to break here
  \parskip 0.5\baselineskip
  \raggedright
  \color{solutiontext}%\slshape
  \normalsize
  \hrule
  \hbox to \textwidth{\vrule height 1ex \hfil \vrule height 1ex}
  \nobreak
  \vskip -\parskip              % cancel out the following parskip
  \textbf{\highlighted{Solution:}}\hskip2em
  \ignorespaces
  \parindent=2em
}
%    \end{macrocode}
% The end of the solution environment is simple, and simply matches
% the box above.
%    \begin{macrocode}
\def\end@formatsolution{%
  \par
  \nobreak
  \vskip -0.5ex
  \hbox to \textwidth{\vrule height 1ex \hfil \vrule height 1ex}
  \hrule
}
%    \end{macrocode}
%
% The content of the \Lenv{solution} environment is balanced \LaTeX\
% text, and so does not have to be complicated; in particular, it does
% not have to have the generality, and the consequent restrictions, of
% for example Eijkhout's \Lpackage{comment} package.  If we're including the
% solutions, then we simply format them in the usual sort of way,
% inside a group; otherwise we're skipping them, so put the contents in a
% box and throw it away. Note that \Lenv{solution} is an environment,
% so we're inside a group at this point.
%    \begin{macrocode}
\if@showsolutions
  \let\solution\@formatsolution
  \let\endsolution\end@formatsolution
%    \end{macrocode}
% In the case where we're not showing solutions, note that we
% \emph{do} format the contents, so any |\global| effects will still
% happen, unless we take action to avoid them.
%
% In particular, |\part|, which is normally redefined in solutions to
% increment \texttt{answerpartnumber} rather than
% \texttt{partnumber}, would increment \texttt{partnumber} in answers
% unless we take action to stop it.
%    \begin{macrocode}
\else
  \def\solution{% make a vbox...
    \par
    \if@insolution
      \ClassError{exam-n}{Misplaced solution}{You can't have a solution within a solution}
    \fi
    \let\endfigure\endfloat@skipsolutions
    \let\endtable\endfloat@skipsolutions
    \examn@dummycaptions     % dummy captions avoid counter increments
    \let\part\relax          % make \part a no-op in discarded {solution}
    \@ifundefined{includepdf}{}{\let\includepdf\examn@disabledpdfpages}
    \setbox\@tempboxa\vbox\bgroup
      \@insolutiontrue
  }
  \def\endsolution{%...and do nothing with this box
    \egroup
  }
\fi
%    \end{macrocode}
%
% \subsubsection{Floats in solutions}
%
% Figures in solutions must be treated specially, since they mustn't
% move outside the solution.  The most straightforward thing seems to
% be to avoid them floating at all.  Additionally, this is probably true of
% figures in the question as well (if a question refers to a figure,
% it's probably civil to have the figure on the same page as the
% text), so redefine {figure} so that in all cases figures are placed
% `here', and never float.  We also add generous amounts of vertical
% space, to encourage figures to stay on the same page as the text
% before them, if this is at all possible.
%
%    \begin{macrocode}
\def\examn@badfloat#1[#2]{
  \ClassError{exam-n}
    {Bad #1 option #2 ignored}
    {In the exam-n class, the 'floating' environments take no argument,\MessageBreak
      and are always placed 'here'}
  \examn@float{#1}}
\def\examn@float#1{%
  % re-using the standard LaTeX parameter means that \caption works
  \def\@captype{#1}
  \setbox\@tempboxa\vbox\bgroup}
%    \end{macrocode}
% End both |{figure}| and |{table}| environments.
% End the |\@tempboxa| and add some space and good breaks before displaying it.
% We're typically in hmode here, but don't depend on it.
%    \begin{macrocode}
\def\examn@endfloat{%
  \egroup                % end \@tempboxa
  \ifvmode\else \unskip \fi % bare \unskip would can an error in vmode
  \nobreak
  % add lots of stretchability, but non-infinite, for the sake of tidiness
  \vskip 0pt plus 0.5\textheight
  \penalty50 % a pagebreak here discards following vskip
  % (cf TeXBook p106; or try \filbreak of p111)
  \vskip 2ex plus -0.5\textheight % negative stretch cancels previous vskip
  \box\@tempboxa
  %\vskip 1ex
  \nobreak
}
\def\endfloat@skipsolutions{%
  % variant when skipping solutions -- end the \@tempboxa and do nothing
  \egroup
}
%    \end{macrocode}
% Now, finally, redefine the figure and table environments in terms of
% these new macros.
%    \begin{macrocode}
\def\figure{%
  \@ifnextchar[{\examn@badfloat{figure}}{\examn@float{figure}}%]
}
\def\table{%
  \@ifnextchar[{\examn@badfloat{table}}{\examn@float{table}}%]
}
\let\endfigure\examn@endfloat
\let\endtable\examn@endfloat
%    \end{macrocode}
% And disable the \texttt{figure*} and \texttt{table*} environments.
%    \begin{macrocode}
\expandafter\def\csname figure*\endcsname{%
  \ClassError{exam-n}
    {Bad environment figure* -- there is no figure* environment in exam-n}
    {Use plain {figure} instead.  See the documentation for discussion}}
\expandafter\def\csname table*\endcsname{%
  \ClassError{exam-n}
    {Bad environment table* -- there is no table* environment in exam-n}
    {Use plain {table} instead.  See the documentation for discussion}}
%    \end{macrocode}
%
% Within these 'floats', we must redefine |\caption|, so that we don't
% increment the float counters.  One motivation for this is so that we don't have
% table numbers changing depending on whether solutions are included
% or not; but since we're implementing the solutions by setting the
% content in a discarded box, it turns out that we get the counter
% increments whether we include the solutions or not.   The following
% definition of |\caption| is just the standard one, with
% |\refstepcounter| removed and `Table nnn' redefined appropriately.
%    \begin{macrocode}
\def\examn@dummycaptions{%
  \def\fnum@figure{\figurename} % 'Figure nnn' changed to just 'Figure'
  \def\fnum@table{\tablename}
  \def\caption{%
    \ifx\@captype\@undefined
      \@latex@error{\noexpand\caption outside float}\@ehd
      \expandafter\@gobble
    \else
      %\refstepcounter\@captype % omit this line from the standard definition
      \expandafter\@firstofone
    \fi
    {\@dblarg{\@caption\@captype}}%
  }
}
%    \end{macrocode}
%
% \subsubsection{Solutions and pdfpages}
%
% It appears that the \Lpackage{pdfpages} package is incompatible with
% the way that I implement \Lopt{noshowsolutions}, largely because (I
% think) it bypasses \LaTeX\ and fiddles with the generated PDF
% directly.  Therefore, we have to disable the \Lpackage{pdfpages}
% support when we're skipping solutions.  We mustn't do this globally,
% since sometimes (for example in a .clo option file's
% constants sheet) we do need pdfpages in the no-show-solutions case.
%    \begin{macrocode}
\def\examn@disabledpdfpages{\@ifnextchar[% ]
  \examn@disabledpdfpages@
  {\examn@disabledpdfpages@[]}}
\def\examn@disabledpdfpages@[#1]#2{\relax}
%    \end{macrocode}
%
% \subsection{End-of-document actions}
%
% Add a number of actions to the end-of-document hook.  Do them here,
% rather than by calling |\AtEndDocument| multiple times, because the
% order matters (in fact, the order here is the same as the order
% they're defined in, but it's best to be explicit about this).
%    \begin{macrocode}
\AtEndDocument{
  \CheckTotalQuestions
  \ClosingText
  \showthe@shouts
  \WriteLastPageLabel}
%    \end{macrocode}
%
% \iffalse extradefs:start
%          This is a magic comment -- see Makefile.
%          these definitions are referred to, in order to document
%          them, both in this class's documentation, and in the
%          notes-for-authors. \fi
%
% \subsection{Other formatting niceties}
%
% Format vectors (the default for |\vec| is a symbol with an arrow
% over it):
%
% Note: the STIX2+(XeLaTeX/LuaLaTeX) support depends on the LaTeX hook
% mechanism released in 2020.  It therefore does not work on versions of
% LaTeX older than that.  There is a check for this above (see
% Sect~\ref{s:compatibility}).
%    \begin{macrocode}
\if@psfonts
  \ifcase\examn@mtselect
    % mathptm fonts
    % This is a very clumsy version, but it appears to be our only option
    \def\vec#1{\mathchoice{\mbox{\boldmath $\displaystyle #1$}}
      {\mbox{\boldmath $ #1$}}
      {\mbox{\boldmath $\scriptstyle #1$}}
      {\mbox{\boldmath $\scriptscriptstyle #1$}}}
    \ifexamn@uprightpi
      \ClassWarning{exam-n}{Can't do uprightpi in [mathptm] -- sorry}
      \let\italicpi\pi
      \examn@uprightpifalse
    \fi
  \or % mathtime (should this be the same for mathtime as for mtpro2?
    \let\vec\mathbf
    \ifexamn@uprightpi
      \ClassWarning{exam-n}{Can't do uprightpi in [mathtime] -- sorry}
      \let\italicpi\pi
      \examn@uprightpifalse
    \fi
  \or % mtpro2
    \let\vec\mathbold
    % \uppi is predefined in mtpro2
    \ifexamn@uprightpi
      \let\italicpi\pi
      \let\pi\uppi
    \fi
  \else
    % STIX2: the unicode-math package provides a \symbf for bold math symbols,
    \ifnum\examn@engine<2       % pdflatex
      \let\vec\mathbf
      % pdftex (or original tex)
      % The following should, I think, create an upright pi, but doesn't
      \def\uppi{\mathrm{\pi}}
      \let\italicpi\pi          %for consistency
      \let\symup\mathrm         %not fully the right thing, but avoid errors below
    \else                       % xelatex or lualatex
      % This is where the dependence on a recent LaTeX enters.
      \let\vec\symbf
      \typeout{stix2: upright=\ifexamn@uprightpi true\else false\fi}
      \AddToHook{begindocument/end}{\gdef\uppi{\symup{𝜋}}}
      \ifexamn@uprightpi
        \AddToHook{begindocument/end}{\gdef\italicpi{\symit{𝜋}}\global\let\pi\uppi}
      \fi
    \fi
  \fi
\else
  % CM fonts: \mathbf doesn't work with greek in CM
  \let\vec\mathbf
  \ifexamn@uprightpi
    % upright greek is hard to do portably, so give up
    % See eg https://tex.stackexchange.com/questions/145926/ for discussion
    \ClassWarning{exam-n}{Can't do uprightpi in [cmfonts] -- sorry}
    \let\italicpi\pi
    \let\uppi\pi                %but avoid errors
    \examn@uprightpifalse
  \fi
\fi
%    \end{macrocode}
%
% Abbreviations for various degrees.
%    \begin{macrocode}
\newcommand\BSc{B.Sc.{}}
\newcommand\MSci{M.Sci.{}}
\newcommand\MSc{M.Sc.{}}
\newcommand\MA{M.A.{}}
\newcommand\MEng{M.Eng.{}}
\newcommand\BEng{B.Eng.{}}
%    \end{macrocode}
%
% Formatting differentials, and the base of natural logs,
% which should be in an upright font.
% See section~\ref{s:othercommands}, or the `notes for authors',
% for a description of these macros.
% The macro |\ddd| is used inside an integral, and includes a leading thinspace
%    \begin{macrocode}
\ifnum\examn@mtselect>2
  % ie, STIX2, and thus using the unicode-math package (see above)
  \def\e{\symup{e}}
  \newcommand{\dd}{\symup{d}}
  \newcommand{\ddd}{\,\symup{d}}
\else
  \def\e{\mathrm{e}}
  \newcommand{\dd}{\mathrm{d}}
  \newcommand{\ddd}{\,\mathrm{d}}
\fi

\def\Diffl{\@ifstar\@Difflflat\@Diffl}
\def\Partial{\@ifstar\@Partialflat\@Partial}
\def\@Partial{\@ifnextchar[{\@@Diffl\partial}{\@@Diffl\partial[]}}
\def\@Partialflat{\@ifnextchar[{\@@Difflflat\partial}{\@@Difflflat\partial[]}}
\def\@Diffl{\@ifnextchar[{\@@Diffl\dd}{\@@Diffl\dd[]}}
\def\@Difflflat{\@ifnextchar[{\@@Difflflat\dd}{\@@Difflflat\dd[]}}
\def\@@Diffl#1[#2]#3#4{%
  \def\@tempa{#2}%
  \ifx\@tempa\empty
    \frac{#1#3}{#1#4}%
  \else
    \frac{{#1}^{#2}#3}{#1{#4}^{#2}}%
  \fi}
\def\@@Difflflat#1[#2]#3#4{%
  \def\@tempa{#2}%
  \ifx\@tempa\empty
    #1#3\mskip-0.8mu/\mskip-1.2mu #1#4%
  \else
    {#1}^{#2}#3\mskip-0.8mu /\mskip-1.2mu #1{#4}^{#2}%
  \fi}
%    \end{macrocode}
%
% Physical units in upright roman.  This macro is now deprecated in
% favour of use of the \Lopt{siunitx} option (which uses the
% \Lpackage{siunitx} package, qv), and it will be removed in a
% minor release after v1.4.
%
% The unstarred version includes leading
% |\thinspace|.  The starred version doesn't, and is used when referring to
% the unit by itself (eg axis is |$B/\units*T$|), and is not qualifying
% a number.
% Separate units with either \texttt{.} or |~|, as in |\units{m~s^{-1}}| or
% |\units{m.s^{-1}}|.
% Note that although \texttt{.} and |~| are both possible unit separators in
% general, the former won't work if used within a table (due to the timing of
% token-reading).
%
% This is a rather simple-minded approach to unit formatting.  For a much more
% comprehensive treatment, see the \texttt{siunitx} package,
% \url{https://ctan.org/pkg/siunitx}, which is now preferred, in place
% of further use of this macro.
%
% Note: there are detailed prescriptions on the formatting of units and symbols in
% ISO-80000-1:2009, Sect. 7.
%    \begin{macrocode}
\def\units{\examn@unitswarning
  \begingroup
  \catcode`\.=\active
  \@ifstar{\let\un@tsspace\relax    \un@ts}%
          {\let\un@tsspace\thinspace\un@ts}}
\begingroup
  \catcode`\.=\active
  \gdef\un@ts#1{\let~\thinspace\let.\thinspace
    \ifmmode
      \un@tsspace\mathrm{#1}%
    \else
      \nobreak$\un@tsspace\mathrm{#1}$%
    \fi
    \endgroup}
\endgroup
\newif\ifexamn@warnunits \examn@warnunitstrue
\def\examn@unitswarning{\ifexamn@warnunits
  \ClassWarning{exam-n}{The units macro will be removed in the next
    version; the [siunitx] option is now on by default, so you can use
    the macros in the siunits package}%
  \global\examn@warnunitsfalse
\fi}
%    \end{macrocode}
% \iffalse extradefs:end % magic comment -- see Makefile \fi
%
% All done.
%    \begin{macrocode}
%</package>
%    \end{macrocode}
% \Finale
%
\endinput