Skip to content

Commit

Permalink
Improve "View Source" for annotated examples
Browse files Browse the repository at this point in the history
  • Loading branch information
ascholerChemeketa authored and rbeezer committed Dec 6, 2024
1 parent 13d5eee commit 4485114
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 70 deletions.
11 changes: 11 additions & 0 deletions css/knowls_default.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
main knowls styles
*/

.source-view__link,
.knowl__link {
cursor: pointer;
margin-left: 0.1em;
Expand All @@ -10,15 +11,22 @@
border-bottom: 1px dotted var(--knowlLinkColor);
}

.source-view {
margin: 0.5em 0;
}

summary.source-view__link,
summary.knowl__link {
display: list-item inline;
}

.source-view__link > *,
.knowl__link > * {
display: inline;
}


.source-view__link:is(:hover, :focus, [open]),
.knowl__link:is(:hover, :focus, [open]) {
background-color: var(--knowlbackground);
border-bottom-color: transparent;
Expand All @@ -32,6 +40,9 @@ summary.knowl__link {
background-color: var(--knowlbackground);
}

.source-view__content {
margin: 0.2em 0;
}

/* No Greg's L in knowls, to save space */
.ptx-content .knowl__content > article:is(.theorem-like, .definition-like, .example-like, .project-like, .objectives, .outcomes, .remark-like, .proof)::after {
Expand Down
3 changes: 3 additions & 0 deletions js_lib/knowl.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,9 @@ class LinkKnowl {
MathJax.typesetPromise([this.outputElement]);
addKnowls(this.outputElement);

// try prism highlighting
Prism.highlightAllUnder(this.outputElement);

// force any scripts (e.g. sagecell) to execute by evaling them
[...this.outputElement.getElementsByTagName("script")].forEach((s) => {
if (
Expand Down
17 changes: 10 additions & 7 deletions xsl/pretext-common.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -1856,13 +1856,16 @@ Book (with parts), "section" at level 3
<xsl:template match="@*" mode="serialize">
<xsl:param name="as-authored-source"/>

<xsl:text> </xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>="</xsl:text>
<xsl:apply-templates mode="serialize-content">
<xsl:with-param name="as-authored-source" select="$as-authored-source"/>
</xsl:apply-templates>
<xsl:text>"</xsl:text>
<!-- never render the @include-source attr -->
<xsl:if test="name() != 'include-source'">
<xsl:text> </xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>="</xsl:text>
<xsl:apply-templates mode="serialize-content">
<xsl:with-param name="as-authored-source" select="$as-authored-source"/>
</xsl:apply-templates>
<xsl:text>"</xsl:text>
</xsl:if>
</xsl:template>

<!-- A namespace "attribute" is not really an attribute, and not captured by @* above. -->
Expand Down
19 changes: 11 additions & 8 deletions xsl/pretext-html.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -607,11 +607,11 @@ along with MathBook XML. If not, see <http://www.gnu.org/licenses/>.
</p>
</xsl:if>
<!-- After the heading, and before the actual guts, we -->
<!-- sometimes annotate with a knowl showing the source -->
<!-- sometimes annotate with the source -->
<!-- of the current element. This calls a stub, unless -->
<!-- a separate stylesheet is used to define the template, -->
<!-- and the method is defined there. -->
<xsl:apply-templates select="." mode="view-source-knowl"/>
<xsl:apply-templates select="." mode="view-source-widget"/>

<!-- This is usually recurrence, so increment heading-level, -->
<!-- but "book" and "article" have an h1 masthead, so if -->
Expand Down Expand Up @@ -4893,15 +4893,14 @@ along with MathBook XML. If not, see <http://www.gnu.org/licenses/>.
<xsl:apply-templates select="." mode="heading-xref-knowl" />
</xsl:if>
<!-- After the heading, and before the actual guts, we -->
<!-- sometimes annotate with a knowl showing the source -->
<!-- sometimes annotate with the source -->
<!-- of the current element. This calls a stub, unless -->
<!-- a separate stylesheet is used to define the template, -->
<!-- and the method is defined there. An "fn" necessarily -->
<!-- comes through here since it is realized as a knowl, -->
<!-- but it is a silly thing to annotate. We skip it -->
<!-- promptly on the receiving end, instead of adding -->
<!-- clutter here. -->
<xsl:apply-templates select="." mode="view-source-knowl"/>
<!-- comes through here, but it is a silly thing to -->
<!-- annotate. We skip it promptly on the receiving end, -->
<!-- instead of adding clutter here. -->
<xsl:apply-templates select="." mode="view-source-widget"/>
<!-- Then actual content, respecting b-original flag -->
<!-- Pass $block-type for Sage cells to know environs -->
<xsl:apply-templates select="." mode="wrapped-content">
Expand Down Expand Up @@ -9056,6 +9055,8 @@ along with MathBook XML. If not, see <http://www.gnu.org/licenses/>.
<!-- See common file for more on language handlers, and "language-prism" template -->
<!-- TODO: maybe ship sanitized "input" to each modal template? -->
<xsl:template match="program[not(ancestor::sidebyside)]|console[not(ancestor::sidebyside)]">
<!-- Possibly annotate with the source -->
<xsl:apply-templates select="." mode="view-source-widget"/>
<xsl:choose>
<!-- if a program is elected as interactive, then -->
<!-- let Runestone do the best it can via the template -->
Expand Down Expand Up @@ -9094,6 +9095,8 @@ along with MathBook XML. If not, see <http://www.gnu.org/licenses/>.
</xsl:template>

<xsl:template match="program[ancestor::sidebyside]|console[ancestor::sidebyside]">
<!-- Possibly annotate with the source -->
<xsl:apply-templates select="." mode="view-source-widget"/>
<xsl:choose>
<!-- if a program is elected as interactive, then -->
<!-- let Runestone do the best it can via the template -->
Expand Down
2 changes: 2 additions & 0 deletions xsl/pretext-runestone.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -2421,6 +2421,8 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.

<!-- Data Files -->
<xsl:template match="datafile" mode="runestone-to-interactive">
<!-- Possibly annotate with the source -->
<xsl:apply-templates select="." mode="view-source-widget"/>
<!-- Some templates and variables are defined in -common for consistency -->

<!-- If there is a child "pre" element, then we build an un-editable -->
Expand Down
95 changes: 40 additions & 55 deletions xsl/pretext-view-source.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,6 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
<!-- terminal. So we kill it with no loss. -->
<xsl:strip-space elements="pretext"/>

<!-- Consistent and unique filenames, in a directory of their own -->
<xsl:template match="*" mode="annotation-knowl-filename">
<xsl:text>annotate/</xsl:text>
<xsl:apply-templates select="." mode="html-id"/>
<xsl:text>.html</xsl:text>
</xsl:template>

<!-- Below, we use a purpose-built attribute to match elements which -->
<!-- have been through the pre-proccessor with their (nearly-)original -->
<!-- progenitors. So we need this id here, late in the game, but we -->
Expand All @@ -80,31 +73,16 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
<!-- a no-op unless the $b-view-source has been set to true() -->
<!-- electively. Not too much of a performance hit as bailing out -->
<!-- is quick, and use is limited to divisions and blocks (roughly). -->
<xsl:template match="*" mode="view-source-knowl">
<xsl:template match="*" mode="view-source-widget">
<!-- Footnotes are silly to annotate, and are also automatically -->
<!-- generated for URLs and hence have no original source, so we -->
<!-- kill them here. Careful experiments suggest these are the -->
<!-- only elements without source. -->
<xsl:variable name="b-banned" select="boolean(self::fn)"/>
<xsl:if test="$b-view-source and not($b-banned)">
<!-- As a variable for consistency -->
<xsl:variable name="filename">
<xsl:apply-templates select="." mode="annotation-knowl-filename"/>
</xsl:variable>

<!-- Part 1: drop the clickable for the knowl via placement -->
<!-- of the application of the "view-source-knowl" template -->
<div>
<!-- A little weak on accessibility -->
<!-- No URL in href, always a modern knowl -->
<!-- No localization of Reveal/Close text -->
<a href="" class="xref" data-knowl="{$filename}" data-reveal-label="Open" data-close-label="Close">
<!-- TODO: internationalize me? -->
<xsl:text>View Source</xsl:text>
</a>
</div>

<!-- Part 2: Create the knowl's content file -->
<!-- Allow for annotations of select elements -->
<xsl:variable name="include-source" select="@include-source = 'yes'"/>
<xsl:if test="($b-view-source and not($b-banned)) or $include-source">
<!-- Part 1: Serialize the source -->
<!-- Save off the id of the element being annotated -->
<xsl:variable name="the-element-id" select="@original-id"/>
<!-- Locate the element with the same id, but in a very early -->
Expand All @@ -124,42 +102,49 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
<!-- the whole stanza left, since it may have a lot of -->
<!-- common indentation (which is why we caught -->
<!-- the preceding indentation). -->
<!-- (5) Run that through "strip-leading-blanks" to get rid -->
<!-- of spaces that may preceed the first element. -->
<!-- NB: the $original-element is used *twice* below, in -->
<!-- order to have the right conteaxt for the manipulations -->
<xsl:variable name="serialized-html">
<xsl:call-template name="sanitize-text">
<xsl:call-template name="strip-leading-blanks">
<xsl:with-param name="text">
<xsl:variable name="lead-in">
<xsl:apply-templates select="$original-element/preceding-sibling::node()[1]" mode="serialize">
<xsl:with-param name="as-authored-source" select="'yes'"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:call-template name="substring-after-last">
<xsl:with-param name="input" select="$lead-in" />
<xsl:with-param name="substr" select="'&#xa;'" />
<xsl:call-template name="sanitize-text">
<xsl:with-param name="text">
<xsl:variable name="lead-in">
<xsl:apply-templates select="$original-element/preceding-sibling::node()[1]" mode="serialize">
<xsl:with-param name="as-authored-source" select="'yes'"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:call-template name="substring-after-last">
<xsl:with-param name="input" select="$lead-in" />
<xsl:with-param name="substr" select="'&#xa;'" />
</xsl:call-template>
<xsl:apply-templates select="$original-element" mode="serialize">
<xsl:with-param name="as-authored-source" select="'yes'"/>
</xsl:apply-templates>
</xsl:with-param>
</xsl:call-template>
<xsl:apply-templates select="$original-element" mode="serialize">
<xsl:with-param name="as-authored-source" select="'yes'"/>
</xsl:apply-templates>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- -->
<!-- Useful for debugging any source manipulations, as it -->
<!-- can be dropped right in the page for quick visual -->
<!-- examination/comparison. -->
<!-- <pre><xsl:value-of select="$serialized-html"/></pre> -->
<!-- -->
<!-- The file part of the knowl -->
<exsl:document href="{$filename}" method="html" indent="yes" encoding="UTF-8" doctype-system="about:legacy-compat">
<html>
<body>
<pre>
<xsl:value-of select="$serialized-html"/>
</pre>
</body>
</html>
</exsl:document>

<!-- Part 2: drop the source into a details on the page -->
<details class="source-view">
<summary class="source-view__link" data-reveal-label="Open" data-close-label="Close">
<!-- TODO: internationalize me? -->
<xsl:text>View Source for </xsl:text><xsl:value-of select="name()"/>
</summary>
<!-- -->
<article class="view-source-view__content" >
<pre>
<code class="language-xml">
<xsl:value-of select="$serialized-html"/>
</code>
</pre>
</article>
</details>

</xsl:if>
</xsl:template>

Expand Down

0 comments on commit 4485114

Please sign in to comment.