@pretextbook/pretext-html 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2672,6 +2672,80 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
2672
2672
  </xsl:variable>
2673
2673
  <xsl:variable name="b-video-privacy" select="$embedded-video-privacy = 'yes'"/>
2674
2674
 
2675
+ <!-- -->
2676
+ <!-- HTML DoenetML Coordinator -->
2677
+ <!-- -->
2678
+
2679
+ <!-- A page carrying many DoenetML activities used to start every one of -->
2680
+ <!-- them the moment the page loaded, and then hold every one of them in -->
2681
+ <!-- memory for as long as the reader stayed. The "coordinator" is a -->
2682
+ <!-- small script, served from the same CDN as the activities themselves, -->
2683
+ <!-- which takes charge of the activity "iframe"s on a page: it starts -->
2684
+ <!-- them a couple at a time as the reader nears them, and puts away the -->
2685
+ <!-- ones the reader has left well behind (saving a reader's work, and -->
2686
+ <!-- restoring it on the way back). A publisher who prefers the older -->
2687
+ <!-- behavior can say "no" here. -->
2688
+ <xsl:variable name="doenetml-coordinator">
2689
+ <xsl:apply-templates select="$publisher-attribute-options/html/interactives/doenetml/pi:pub-attribute[@name='coordinator']" mode="set-pubfile-variable"/>
2690
+ </xsl:variable>
2691
+ <xsl:variable name="b-doenetml-coordinator" select="$doenetml-coordinator = 'yes'"/>
2692
+
2693
+ <!-- Each DoenetML activity ordinarily gets a dedicated web worker to run -->
2694
+ <!-- in, which is the largest part of what an activity costs. With the -->
2695
+ <!-- coordinator in charge, the activities on a page can instead share a -->
2696
+ <!-- pool of workers that the coordinator owns. Only consulted when the -->
2697
+ <!-- coordinator is in use. -->
2698
+ <xsl:variable name="doenetml-shared-core-workers">
2699
+ <xsl:apply-templates select="$publisher-attribute-options/html/interactives/doenetml/pi:pub-attribute[@name='shared-core-workers']" mode="set-pubfile-variable"/>
2700
+ </xsl:variable>
2701
+ <xsl:variable name="b-doenetml-shared-core-workers" select="$doenetml-shared-core-workers = 'yes'"/>
2702
+
2703
+ <!-- How many DoenetML activities the coordinator keeps running at once, -->
2704
+ <!-- and how many it allows to be starting up at once. The defaults suit -->
2705
+ <!-- a reader on modest hardware; a publisher whose activities are small, -->
2706
+ <!-- or whose readers are known to have capable machines, may raise them. -->
2707
+ <!-- Freeform entries, validated here to positive integers: the script -->
2708
+ <!-- reads each one as a number, and an unusable number would leave it -->
2709
+ <!-- forever waiting for room, never starting any activity at all. -->
2710
+ <xsl:variable name="doenetml-max-live-viewers-entered">
2711
+ <xsl:apply-templates select="$publisher-attribute-options/html/interactives/doenetml/pi:pub-attribute[@name='max-live-viewers']" mode="set-pubfile-variable"/>
2712
+ </xsl:variable>
2713
+ <xsl:variable name="doenetml-max-live-viewers">
2714
+ <xsl:choose>
2715
+ <xsl:when test="(number($doenetml-max-live-viewers-entered) = round(number($doenetml-max-live-viewers-entered))) and (number($doenetml-max-live-viewers-entered) &gt; 0)">
2716
+ <xsl:value-of select="round(number($doenetml-max-live-viewers-entered))"/>
2717
+ </xsl:when>
2718
+ <xsl:otherwise>
2719
+ <xsl:message>PTX:FALLBACK: the DoenetML "max-live-viewers" in the publication file ("<xsl:value-of select="$doenetml-max-live-viewers-entered"/>") must be a positive whole number of activities, using the default, 3</xsl:message>
2720
+ <xsl:text>3</xsl:text>
2721
+ </xsl:otherwise>
2722
+ </xsl:choose>
2723
+ </xsl:variable>
2724
+ <xsl:variable name="doenetml-max-concurrent-boots-entered">
2725
+ <xsl:apply-templates select="$publisher-attribute-options/html/interactives/doenetml/pi:pub-attribute[@name='max-concurrent-boots']" mode="set-pubfile-variable"/>
2726
+ </xsl:variable>
2727
+ <xsl:variable name="doenetml-max-concurrent-boots">
2728
+ <xsl:choose>
2729
+ <xsl:when test="(number($doenetml-max-concurrent-boots-entered) = round(number($doenetml-max-concurrent-boots-entered))) and (number($doenetml-max-concurrent-boots-entered) &gt; 0)">
2730
+ <xsl:value-of select="round(number($doenetml-max-concurrent-boots-entered))"/>
2731
+ </xsl:when>
2732
+ <xsl:otherwise>
2733
+ <xsl:message>PTX:FALLBACK: the DoenetML "max-concurrent-boots" in the publication file ("<xsl:value-of select="$doenetml-max-concurrent-boots-entered"/>") must be a positive whole number of activities, using the default, 2</xsl:message>
2734
+ <xsl:text>2</xsl:text>
2735
+ </xsl:otherwise>
2736
+ </xsl:choose>
2737
+ </xsl:variable>
2738
+
2739
+ <!-- A GeoGebra applet starts as soon as its page does, and a page carrying -->
2740
+ <!-- several of them can be slow to settle on a modest machine. A publisher -->
2741
+ <!-- may instead hold each one behind a play button, so an applet starts only -->
2742
+ <!-- when a reader asks for it. Off by default: the reader of a page with one -->
2743
+ <!-- or two applets should not have to click to see them. -->
2744
+ <xsl:variable name="geogebra-play-button">
2745
+ <xsl:apply-templates select="$publisher-attribute-options/html/interactives/geogebra/pi:pub-attribute[@name='play-button']" mode="set-pubfile-variable"/>
2746
+ </xsl:variable>
2747
+ <xsl:variable name="b-geogebra-play-button" select="$geogebra-play-button = 'yes'"/>
2748
+
2675
2749
  <!-- -->
2676
2750
  <!-- HTML Platform Options -->
2677
2751
  <!-- -->
@@ -3608,9 +3682,14 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
3608
3682
  </desmos>
3609
3683
  <doenetml>
3610
3684
  <pi:pub-attribute name="resize-behavior" default="fixed-height" options="responsive"/>
3685
+ <pi:pub-attribute name="coordinator" default="yes" options="no"/>
3686
+ <pi:pub-attribute name="shared-core-workers" default="yes" options="no"/>
3687
+ <pi:pub-attribute name="max-live-viewers" default="3" freeform="yes"/>
3688
+ <pi:pub-attribute name="max-concurrent-boots" default="2" freeform="yes"/>
3611
3689
  </doenetml>
3612
3690
  <geogebra>
3613
3691
  <pi:pub-attribute name="resize-behavior" default="fixed-height" options="responsive"/>
3692
+ <pi:pub-attribute name="play-button" default="no" options="yes"/>
3614
3693
  </geogebra>
3615
3694
  <iframe>
3616
3695
  <pi:pub-attribute name="resize-behavior" default="fixed-height" options="responsive"/>
@@ -49,6 +49,37 @@
49
49
  <!-- necessity of this scheme. -->
50
50
  <xsl:variable name="b-extracting-pg" select="true()"/>
51
51
 
52
+ <!-- We need latex packages and macros, but we must exclude -->
53
+ <!-- \lt and \gt. This is because WeBWorK/PG already loads -->
54
+ <!-- those. And their duplication in WeBWorK hardcopy output -->
55
+ <!-- is not permitted. -->
56
+ <xsl:variable name="latex-macros">
57
+ <xsl:variable name="latex-left-justified">
58
+ <xsl:call-template name="sanitize-text">
59
+ <xsl:with-param name="text">
60
+ <xsl:value-of select="$docinfo/macros" />
61
+ </xsl:with-param>
62
+ </xsl:call-template>
63
+ </xsl:variable>
64
+ <xsl:call-template name="latex-macro-first-percent">
65
+ <xsl:with-param name="latex-code">
66
+ <xsl:value-of select="$latex-left-justified" />
67
+ </xsl:with-param>
68
+ </xsl:call-template>
69
+ <xsl:text>\newcommand{\amp}{&amp;}&#xa;</xsl:text>
70
+ </xsl:variable>
71
+
72
+ <xsl:variable name="latex-packages">
73
+ <xsl:for-each select="$docinfo/math-package">
74
+ <xsl:if test="not(normalize-space(@mathjax-name) = '')">
75
+ <xsl:text>\require{</xsl:text>
76
+ <xsl:value-of select="@mathjax-name"/>
77
+ <xsl:apply-templates/>
78
+ <xsl:text>}&#xa;</xsl:text>
79
+ </xsl:if>
80
+ </xsl:for-each>
81
+ </xsl:variable>
82
+
52
83
  <!-- We are outputting perl code, and there is no reason to output -->
53
84
  <!-- anything other than "text" -->
54
85
  <xsl:output method="text" encoding="UTF-8" />
@@ -71,7 +102,9 @@
71
102
  </xsl:variable>
72
103
  <xsl:variable name="macro-file-content">
73
104
  <xsl:call-template name="header"/>
105
+ <xsl:apply-templates select="$document-root" mode="latex-macros"/>
74
106
  <xsl:apply-templates select="$document-root" mode="latex-image-preamble"/>
107
+ <xsl:text>1;&#xa;</xsl:text>
75
108
  </xsl:variable>
76
109
  <exsl:document href="{$macro-file-name}" method="text">
77
110
  <xsl:call-template name="sanitize-text">
@@ -97,6 +130,24 @@
97
130
  </xsl:if>
98
131
  </xsl:template>
99
132
 
133
+ <xsl:template match="book|article" mode="latex-macros">
134
+ <xsl:text>TEXT(&#xa;</xsl:text>
135
+ <xsl:text> MODES(&#xa;</xsl:text>
136
+ <xsl:text> HTML => '&lt;div style="display:none;">' . general_math_ev3(&lt;&lt;'EOF') . '&lt;/div>',&#xa;</xsl:text>
137
+ <xsl:value-of select="$latex-packages"/>
138
+ <xsl:value-of select="$latex-macros"/>
139
+ <xsl:text>EOF&#xa;</xsl:text>
140
+ <xsl:text> TeX => '\ifdefined\ptxmacros\else ' . &lt;&lt;'EOF'&#xa;</xsl:text>
141
+ <xsl:value-of select="$latex-packages"/>
142
+ <xsl:value-of select="$latex-macros"/>
143
+ <xsl:text>\def\ptxmacros{}&#xa;</xsl:text>
144
+ <xsl:text>EOF&#xa;</xsl:text>
145
+ <xsl:text>. '\fi',&#xa;</xsl:text>
146
+ <xsl:text> PTX => ''&#xa;</xsl:text>
147
+ <xsl:text> )&#xa;</xsl:text>
148
+ <xsl:text>);&#xa;&#xa;</xsl:text>
149
+ </xsl:template>
150
+
100
151
  <xsl:template name="header">
101
152
  <xsl:text>#############################################################################&#xa;</xsl:text>
102
153
  <xsl:text># This macro library supports WeBWorK problems from the PreTeXt project named&#xa;</xsl:text>
@@ -443,6 +443,88 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
443
443
  </xsl:call-template>
444
444
  </xsl:variable>
445
445
 
446
+ <!--========================================================================-->
447
+ <!-- test css-string-escape -->
448
+ <xsl:variable name="css-string-escape-plain">
449
+ <xsl:variable name="test-val">
450
+ <xsl:call-template name="css-string-escape">
451
+ <xsl:with-param name="text" select="'(a)'"/>
452
+ </xsl:call-template>
453
+ </xsl:variable>
454
+ <xsl:call-template name="assert-equal">
455
+ <xsl:with-param name="expected" select="'(a)'"/>
456
+ <xsl:with-param name="actual" select="$test-val"/>
457
+ <xsl:with-param name="test-name" select="'css-string-escape-plain'"/>
458
+ </xsl:call-template>
459
+ </xsl:variable>
460
+
461
+ <xsl:variable name="css-string-escape-empty">
462
+ <xsl:variable name="test-val">
463
+ <xsl:call-template name="css-string-escape">
464
+ <xsl:with-param name="text" select="''"/>
465
+ </xsl:call-template>
466
+ </xsl:variable>
467
+ <xsl:call-template name="assert-equal">
468
+ <xsl:with-param name="expected" select="''"/>
469
+ <xsl:with-param name="actual" select="$test-val"/>
470
+ <xsl:with-param name="test-name" select="'css-string-escape-empty'"/>
471
+ </xsl:call-template>
472
+ </xsl:variable>
473
+
474
+ <xsl:variable name="css-string-escape-apostrophe">
475
+ <xsl:variable name="test-val">
476
+ <xsl:call-template name="css-string-escape">
477
+ <xsl:with-param name="text">don't</xsl:with-param>
478
+ </xsl:call-template>
479
+ </xsl:variable>
480
+ <xsl:call-template name="assert-equal">
481
+ <xsl:with-param name="expected">don\'t</xsl:with-param>
482
+ <xsl:with-param name="actual" select="$test-val"/>
483
+ <xsl:with-param name="test-name" select="'css-string-escape-apostrophe'"/>
484
+ </xsl:call-template>
485
+ </xsl:variable>
486
+
487
+ <xsl:variable name="css-string-escape-backslash">
488
+ <xsl:variable name="test-val">
489
+ <xsl:call-template name="css-string-escape">
490
+ <xsl:with-param name="text">a\b</xsl:with-param>
491
+ </xsl:call-template>
492
+ </xsl:variable>
493
+ <xsl:call-template name="assert-equal">
494
+ <xsl:with-param name="expected">a\\b</xsl:with-param>
495
+ <xsl:with-param name="actual" select="$test-val"/>
496
+ <xsl:with-param name="test-name" select="'css-string-escape-backslash'"/>
497
+ </xsl:call-template>
498
+ </xsl:variable>
499
+
500
+ <!-- less-than becomes its code point with a delimiting space, so -->
501
+ <!-- escaped text can never close an enclosing "style" element -->
502
+ <xsl:variable name="css-string-escape-less-than">
503
+ <xsl:variable name="test-val">
504
+ <xsl:call-template name="css-string-escape">
505
+ <xsl:with-param name="text">a&lt;b</xsl:with-param>
506
+ </xsl:call-template>
507
+ </xsl:variable>
508
+ <xsl:call-template name="assert-equal">
509
+ <xsl:with-param name="expected">a\3c b</xsl:with-param>
510
+ <xsl:with-param name="actual" select="$test-val"/>
511
+ <xsl:with-param name="test-name" select="'css-string-escape-less-than'"/>
512
+ </xsl:call-template>
513
+ </xsl:variable>
514
+
515
+ <xsl:variable name="css-string-escape-hostile">
516
+ <xsl:variable name="test-val">
517
+ <xsl:call-template name="css-string-escape">
518
+ <xsl:with-param name="text">'a\&lt;/style></xsl:with-param>
519
+ </xsl:call-template>
520
+ </xsl:variable>
521
+ <xsl:call-template name="assert-equal">
522
+ <xsl:with-param name="expected">\'a\\\3c /style></xsl:with-param>
523
+ <xsl:with-param name="actual" select="$test-val"/>
524
+ <xsl:with-param name="test-name" select="'css-string-escape-hostile'"/>
525
+ </xsl:call-template>
526
+ </xsl:variable>
527
+
446
528
  <!--========================================================================-->
447
529
 
448
530
  <!-- "main" -->
@@ -152,6 +152,14 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
152
152
  <xsl:text> </xsl:text>
153
153
  <xsl:value-of select="$baseurl"/>
154
154
  <xsl:text>&#xa;</xsl:text>
155
+ <!-- -->
156
+ <!-- 2026-08-28 percent widths are relative to this, and an interactive -->
157
+ <!-- is built at this width, so preview screenshots need to know it -->
158
+ <xsl:text>html-design-width</xsl:text>
159
+ <xsl:text> </xsl:text>
160
+ <xsl:value-of select="$html-design-width"/>
161
+ <xsl:text>&#xa;</xsl:text>
162
+ <!-- -->
155
163
  <!-- 2026-06-25 platform host for html -->
156
164
  <xsl:text>host-platform</xsl:text>
157
165
  <xsl:text> </xsl:text>