@pretextbook/pretext-html 0.14.0 → 0.16.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.
- package/assets/upstream.json +1 -1
- package/assets/xsl/extract-interactive.xsl +8 -0
- package/assets/xsl/extract-pg.xsl +1 -75
- package/assets/xsl/pretext-assembly.xsl +34 -7
- package/assets/xsl/pretext-common.xsl +21 -0
- package/assets/xsl/pretext-epub.xsl +8 -0
- package/assets/xsl/pretext-fo.xsl +10 -0
- package/assets/xsl/pretext-html.xsl +159 -60
- package/assets/xsl/pretext-jupyter.xsl +4 -0
- package/assets/xsl/pretext-revealjs.xsl +101 -0
- package/assets/xsl/pretext-text-utilities.xsl +30 -0
- package/assets/xsl/publisher-variables.xsl +79 -0
- package/assets/xsl/support/pretext-pg-macros.xsl +51 -0
- package/assets/xsl/tests/pretext-text-utilities-test.xsl +82 -0
- package/assets/xsl/utilities/report-publisher-variables.xsl +8 -0
- package/assets/xsl-bundle.json +1 -1
- package/dist/{cli-BkTQ4BJP.js → cli-ox-z2TCZ.js} +4 -4
- package/dist/cli.js +1 -1
- package/dist/html-static.d.ts +2 -2
- package/dist/index.browser.d.ts +2 -0
- package/dist/index.browser.js +858 -514
- package/dist/index.d.ts +2 -0
- package/dist/index.js +34 -29
- package/dist/live-patch.d.ts +100 -0
- package/dist/live-patch.js +346 -0
- package/package.json +9 -1
|
@@ -525,6 +525,107 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
|
|
|
525
525
|
</p>
|
|
526
526
|
</xsl:template>
|
|
527
527
|
|
|
528
|
+
<!-- A paragraph containing displays - lists ("ol", "ul", "dl"), -->
|
|
529
|
+
<!-- display mathematics ("md"), or code display ("cd") - cannot -->
|
|
530
|
+
<!-- be realized as a single HTML "p". Each display renders as -->
|
|
531
|
+
<!-- an element that HTML forbids inside a "p" (a list, a "pre", -->
|
|
532
|
+
<!-- a "div" of online mathematics), and a browser recovers by -->
|
|
533
|
+
<!-- closing the paragraph at the display, leaving the remainder -->
|
|
534
|
+
<!-- orphaned outside any paragraph. So, just as in the HTML -->
|
|
535
|
+
<!-- conversion, such a paragraph is exploded: each maximal run -->
|
|
536
|
+
<!-- of inline content becomes a "p" (an empty run produces -->
|
|
537
|
+
<!-- nothing at all), with the displays standing in between. -->
|
|
538
|
+
<!-- (With embedded mathematics a display is a "span", legal -->
|
|
539
|
+
<!-- within a "p" and block-level only by styling, but it is -->
|
|
540
|
+
<!-- exploded identically: the presentation is the same and the -->
|
|
541
|
+
<!-- template stays uniform.) -->
|
|
542
|
+
<!-- -->
|
|
543
|
+
<!-- This realization is demanded by the output format alone; it -->
|
|
544
|
+
<!-- is not the undoing of upstream normalization. An author may -->
|
|
545
|
+
<!-- place a display mid-paragraph, so the explosion is necessary -->
|
|
546
|
+
<!-- even when no paragraph is ever manufactured. Conversely, -->
|
|
547
|
+
<!-- when the assembly wraps a bare list on a "slide" in a -->
|
|
548
|
+
<!-- paragraph, so the internal tree presents the main grammar's -->
|
|
549
|
+
<!-- one shape to every consumer, that paragraph's inline runs -->
|
|
550
|
+
<!-- are all empty and the exploded output is exactly the bare -->
|
|
551
|
+
<!-- list again. The two maneuvers are complementary: normalize -->
|
|
552
|
+
<!-- toward the grammar internally, adapt to the medium at output. -->
|
|
553
|
+
<!-- -->
|
|
554
|
+
<!-- A paused paragraph must advance as a single unit, so its -->
|
|
555
|
+
<!-- exploded parts ride together in one container carrying the -->
|
|
556
|
+
<!-- "fragment" class. -->
|
|
557
|
+
<xsl:template match="p[ol|ul|dl|md[mrow]|cd]">
|
|
558
|
+
<xsl:choose>
|
|
559
|
+
<xsl:when test="@pause = 'yes'">
|
|
560
|
+
<div class="fragment">
|
|
561
|
+
<xsl:apply-templates select="." mode="exploded-paragraph"/>
|
|
562
|
+
</div>
|
|
563
|
+
</xsl:when>
|
|
564
|
+
<xsl:otherwise>
|
|
565
|
+
<xsl:apply-templates select="." mode="exploded-paragraph"/>
|
|
566
|
+
</xsl:otherwise>
|
|
567
|
+
</xsl:choose>
|
|
568
|
+
</xsl:template>
|
|
569
|
+
|
|
570
|
+
<!-- The explosion itself, patterned on the HTML conversion's -->
|
|
571
|
+
<!-- template for a "p" with displays, simplified: no HTML id, no -->
|
|
572
|
+
<!-- permalink, no knowl machinery on the pieces of a slide. -->
|
|
573
|
+
<xsl:template match="p" mode="exploded-paragraph">
|
|
574
|
+
<xsl:variable name="displays" select="ol|ul|dl|md[mrow]|cd"/>
|
|
575
|
+
<!-- content prior to the first display; if empty -->
|
|
576
|
+
<!-- we do not manufacture an empty paragraph -->
|
|
577
|
+
<xsl:variable name="initial" select="$displays[1]/preceding-sibling::*|$displays[1]/preceding-sibling::text()"/>
|
|
578
|
+
<xsl:variable name="initial-content">
|
|
579
|
+
<xsl:apply-templates select="$initial"/>
|
|
580
|
+
</xsl:variable>
|
|
581
|
+
<!-- XSLT 1.0: RTF is just a string if not converted to node set -->
|
|
582
|
+
<xsl:if test="not($initial-content = '')">
|
|
583
|
+
<p>
|
|
584
|
+
<xsl:copy-of select="$initial-content"/>
|
|
585
|
+
</p>
|
|
586
|
+
</xsl:if>
|
|
587
|
+
<!-- for each display: the display itself, then trailing content -->
|
|
588
|
+
<xsl:for-each select="$displays">
|
|
589
|
+
<xsl:apply-templates select="."/>
|
|
590
|
+
<xsl:variable name="rightward" select="following-sibling::*|following-sibling::text()"/>
|
|
591
|
+
<xsl:variable name="next-display" select="following-sibling::*[self::ul or self::ol or self::dl or self::md[mrow] or self::cd][1]"/>
|
|
592
|
+
<xsl:choose>
|
|
593
|
+
<xsl:when test="$next-display">
|
|
594
|
+
<xsl:variable name="leftward" select="$next-display/preceding-sibling::*|$next-display/preceding-sibling::text()"/>
|
|
595
|
+
<!-- device below forms set intersection -->
|
|
596
|
+
<xsl:variable name="common" select="$rightward[count(. | $leftward) = count($leftward)]"/>
|
|
597
|
+
<xsl:variable name="common-content">
|
|
598
|
+
<xsl:apply-templates select="$common"/>
|
|
599
|
+
</xsl:variable>
|
|
600
|
+
<xsl:if test="not($common-content = '')">
|
|
601
|
+
<p>
|
|
602
|
+
<!-- interstitial content arising from an authored -->
|
|
603
|
+
<!-- "intertext" is marked, as in the HTML -->
|
|
604
|
+
<!-- conversion, for styling purposes -->
|
|
605
|
+
<xsl:if test="$common[self::pi:intertext]">
|
|
606
|
+
<xsl:attribute name="class">
|
|
607
|
+
<xsl:text>intertext</xsl:text>
|
|
608
|
+
</xsl:attribute>
|
|
609
|
+
</xsl:if>
|
|
610
|
+
<xsl:copy-of select="$common-content"/>
|
|
611
|
+
</p>
|
|
612
|
+
</xsl:if>
|
|
613
|
+
</xsl:when>
|
|
614
|
+
<xsl:otherwise>
|
|
615
|
+
<!-- finish the trailing content, if nonempty -->
|
|
616
|
+
<xsl:variable name="common-content">
|
|
617
|
+
<xsl:apply-templates select="$rightward"/>
|
|
618
|
+
</xsl:variable>
|
|
619
|
+
<xsl:if test="not($common-content = '')">
|
|
620
|
+
<p>
|
|
621
|
+
<xsl:copy-of select="$common-content"/>
|
|
622
|
+
</p>
|
|
623
|
+
</xsl:if>
|
|
624
|
+
</xsl:otherwise>
|
|
625
|
+
</xsl:choose>
|
|
626
|
+
</xsl:for-each>
|
|
627
|
+
</xsl:template>
|
|
628
|
+
|
|
528
629
|
<!-- Images get wrapped in a div with @class="fragment" if they are -->
|
|
529
630
|
<!-- paused -->
|
|
530
631
|
<xsl:template match="image[not(ancestor::sidebyside) and (@pause='yes')]">
|
|
@@ -1299,4 +1299,34 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
|
|
|
1299
1299
|
</xsl:choose>
|
|
1300
1300
|
</xsl:template>
|
|
1301
1301
|
|
|
1302
|
+
<!-- Escape arbitrary text for a single-quoted CSS string: -->
|
|
1303
|
+
<!-- backslash and apostrophe by a backslash, and a less-than by -->
|
|
1304
|
+
<!-- its code point (with delimiting space). The last means the -->
|
|
1305
|
+
<!-- text can never terminate an enclosing HTML "style" element -->
|
|
1306
|
+
<!-- prematurely, since an HTML parser ends such an element at a -->
|
|
1307
|
+
<!-- literal "</style" no matter the surrounding CSS syntax. -->
|
|
1308
|
+
<xsl:template name="css-string-escape">
|
|
1309
|
+
<xsl:param name="text"/>
|
|
1310
|
+
<xsl:if test="not($text = '')">
|
|
1311
|
+
<xsl:variable name="first" select="substring($text, 1, 1)"/>
|
|
1312
|
+
<xsl:choose>
|
|
1313
|
+
<xsl:when test="$first = '\'">
|
|
1314
|
+
<xsl:text>\\</xsl:text>
|
|
1315
|
+
</xsl:when>
|
|
1316
|
+
<xsl:when test='$first = "'"'>
|
|
1317
|
+
<xsl:text>\'</xsl:text>
|
|
1318
|
+
</xsl:when>
|
|
1319
|
+
<xsl:when test="$first = '<'">
|
|
1320
|
+
<xsl:text>\3c </xsl:text>
|
|
1321
|
+
</xsl:when>
|
|
1322
|
+
<xsl:otherwise>
|
|
1323
|
+
<xsl:value-of select="$first"/>
|
|
1324
|
+
</xsl:otherwise>
|
|
1325
|
+
</xsl:choose>
|
|
1326
|
+
<xsl:call-template name="css-string-escape">
|
|
1327
|
+
<xsl:with-param name="text" select="substring($text, 2)"/>
|
|
1328
|
+
</xsl:call-template>
|
|
1329
|
+
</xsl:if>
|
|
1330
|
+
</xsl:template>
|
|
1331
|
+
|
|
1302
1332
|
</xsl:stylesheet>
|
|
@@ -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) > 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) > 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}{&}
</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>}
</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;
</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(
</xsl:text>
|
|
135
|
+
<xsl:text> MODES(
</xsl:text>
|
|
136
|
+
<xsl:text> HTML => '<div style="display:none;">' . general_math_ev3(<<'EOF') . '</div>',
</xsl:text>
|
|
137
|
+
<xsl:value-of select="$latex-packages"/>
|
|
138
|
+
<xsl:value-of select="$latex-macros"/>
|
|
139
|
+
<xsl:text>EOF
</xsl:text>
|
|
140
|
+
<xsl:text> TeX => '\ifdefined\ptxmacros\else ' . <<'EOF'
</xsl:text>
|
|
141
|
+
<xsl:value-of select="$latex-packages"/>
|
|
142
|
+
<xsl:value-of select="$latex-macros"/>
|
|
143
|
+
<xsl:text>\def\ptxmacros{}
</xsl:text>
|
|
144
|
+
<xsl:text>EOF
</xsl:text>
|
|
145
|
+
<xsl:text>. '\fi',
</xsl:text>
|
|
146
|
+
<xsl:text> PTX => ''
</xsl:text>
|
|
147
|
+
<xsl:text> )
</xsl:text>
|
|
148
|
+
<xsl:text>);

</xsl:text>
|
|
149
|
+
</xsl:template>
|
|
150
|
+
|
|
100
151
|
<xsl:template name="header">
|
|
101
152
|
<xsl:text>#############################################################################
</xsl:text>
|
|
102
153
|
<xsl:text># This macro library supports WeBWorK problems from the PreTeXt project named
</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<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\</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>
</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>
</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>
|