<?xml version="1.0" encoding="utf-8"?>

<!--
Book-like MATLAB publish XSL stylesheet.
Based on the default MathWorks mscript-to-HTML stylesheet,
modified for cleaner typography and MathJax LaTeX rendering.
-->

<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#160;"> <!ENTITY reg "&#174;"> ]>

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:mwsh="http://www.mathworks.com/namespace/mcode/v1/syntaxhighlight.dtd"
  exclude-result-prefixes="mwsh">

  <xsl:output method="html" indent="yes" omit-xml-declaration="yes"/>

  <xsl:variable name="title">
    <xsl:variable name="dTitle" select="//steptitle[@style='document']"/>
    <xsl:choose>
      <xsl:when test="$dTitle">
        <xsl:value-of select="$dTitle"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="mscript/m-file"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>


  <xsl:template match="mscript">
    <html>
      <head>
        <xsl:comment>
This HTML was auto-generated from MATLAB code.
To make changes, update the MATLAB code and republish this document.
        </xsl:comment>

        <meta charset="utf-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1"/>

        <title>
          <xsl:value-of select="$title"/>
        </title>

        <meta name="generator">
          <xsl:attribute name="content">
            <xsl:text>MATLAB </xsl:text>
            <xsl:value-of select="version"/>
          </xsl:attribute>
        </meta>

        <link rel="schema.DC" href="http://purl.org/dc/elements/1.1/" />

        <meta name="DC.date">
          <xsl:attribute name="content">
            <xsl:value-of select="date"/>
          </xsl:attribute>
        </meta>

        <meta name="DC.source">
          <xsl:attribute name="content">
            <xsl:value-of select="m-file"/>
            <xsl:text>.m</xsl:text>
          </xsl:attribute>
        </meta>

        <xsl:call-template name="stylesheet"/>

        <!-- MathJax configuration -->
        <script type="text/javascript">
window.MathJax = {
  tex: {
    inlineMath: [['$', '$'], ['\\(', '\\)']],
    displayMath: [['$$', '$$'], ['\\[', '\\]']],
    processEscapes: true
  },
  svg: {
    fontCache: 'global'
  }
};
        </script>

        <script type="text/javascript" async="async"
          src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
        </script>

      </head>

      <body>
        <xsl:call-template name="header"/>

        <main class="content">

          <!-- Determine if there should be an introduction section. -->
          <xsl:variable name="hasIntro" select="count(cell[@style = 'overview'])"/>

          <!-- If there is an introduction, display it. -->
          <xsl:if test="$hasIntro">
            <h1>
              <xsl:apply-templates select="cell[1]/steptitle"/>
            </h1>
            <xsl:comment>introduction</xsl:comment>
            <xsl:apply-templates select="cell[1]/text"/>
            <xsl:apply-templates select="cell[1]/mcodeoutput"/>
            <xsl:comment>/introduction</xsl:comment>
          </xsl:if>

          <xsl:variable name="body-cells" select="cell[not(@style = 'overview')]"/>

          <!-- Include contents if there are titles for any subsections. -->
          <xsl:if test="count(cell/steptitle[not(@style = 'document')])">
            <xsl:call-template name="contents">
              <xsl:with-param name="body-cells" select="$body-cells"/>
            </xsl:call-template>
          </xsl:if>

          <!-- Loop over each cell. -->
          <xsl:for-each select="$body-cells">

            <!-- Title of cell. -->
            <xsl:if test="steptitle">
              <xsl:variable name="headinglevel">
                <xsl:choose>
                  <xsl:when test="steptitle[@style = 'document']">h1</xsl:when>
                  <xsl:otherwise>h2</xsl:otherwise>
                </xsl:choose>
              </xsl:variable>

              <xsl:element name="{$headinglevel}">
                <xsl:if test="not(steptitle[@style = 'document'])">
                  <xsl:attribute name="id">
                    <xsl:value-of select="position()"/>
                  </xsl:attribute>
                </xsl:if>
                <xsl:apply-templates select="steptitle"/>
              </xsl:element>
            </xsl:if>

            <!-- Contents of each cell. -->
            <xsl:apply-templates select="text"/>
            <xsl:apply-templates select="mcode-xmlized"/>
            <xsl:apply-templates select="mcodeoutput|img"/>

          </xsl:for-each>

          <xsl:call-template name="footer"/>

        </main>

        <xsl:apply-templates select="originalCode"/>

      </body>
    </html>
  </xsl:template>


  <xsl:template name="stylesheet">
    <style type="text/css">

/* ------------------------------
   Page and typography
------------------------------ */

html {
  background: #f4f1ea;
}

html body {
  margin: 0;
  font-family: Georgia, "Times New Roman", Times, serif;
  font-size: 18px;
  line-height: 1.65;
  color: #222;
  background: #f4f1ea;
}

.content {
  max-width: clamp(760px, 85vw, 1100px);
  margin: 48px auto 96px auto;
  padding: 64px 80px;
  background: #fffdf8;
  box-shadow: 0 8px 30px rgba(0,0,0,0.08);
  border-radius: 4px;
}

/* ------------------------------
   Headings
------------------------------ */

h1 {
  font-family: Georgia, "Times New Roman", Times, serif;
  font-size: 2.4em;
  line-height: 1.15;
  font-weight: normal;
  color: #111;
  margin: 0 0 1.2em 0;
  padding-bottom: 0.4em;
  border-bottom: 2px solid #222;
}

h2 {
  font-family: Georgia, "Times New Roman", Times, serif;
  font-size: 1.55em;
  line-height: 1.25;
  font-weight: normal;
  color: #111;
  margin: 2.2em 0 0.75em 0;
  padding-bottom: 0.25em;
  border-bottom: 1px solid #ddd;
}

h3 {
  font-family: Georgia, "Times New Roman", Times, serif;
  font-size: 1.25em;
  margin: 1.8em 0 0.5em 0;
  color: #111;
}

/* The first h1 can act as a book chapter title. */
.content > h1:first-of-type {
  font-size: 2.8em;
  text-align: center;
  border-bottom: none;
  margin-bottom: 1.5em;
}

/* ------------------------------
   Body text
------------------------------ */

p {
  margin: 0 0 1.1em 0;
}

a {
  color: #005fce;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

a:visited {
  color: #004aa0;
}

em,
i {
  font-style: italic;
}

strong,
b {
  font-weight: bold;
}

/* ------------------------------
   Lists
------------------------------ */

ul,
ol {
  margin: 0 0 1.25em 2em;
  padding: 0;
}

ul {
  list-style: square;
}

ol {
  list-style: decimal;
}

li {
  margin-bottom: 0.45em;
}

/* ------------------------------
   Code
------------------------------ */

pre,
code,
tt {
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
}

tt {
  font-size: 0.95em;
}

pre {
  font-size: 0.85em;
  line-height: 1.45;
  margin: 1.2em 0;
  overflow-x: auto;
}

pre.codeinput {
  padding: 1em;
  border: 1px solid #ddd;
  background: #f7f7f7;
  border-radius: 4px;
}

pre.codeoutput {
  padding: 1em;
  color: #444;
  background: #fbfbfb;
  border-left: 3px solid #ccc;
}

pre.error {
  color: #b00020;
  background: #fff0f0;
  border-left: 3px solid #b00020;
  padding: 1em;
}

/* Syntax highlighting from MATLAB. */
span.keyword {
  color: #0000ff;
}

span.comment {
  color: #228b22;
}

span.string {
  color: #a020f0;
}

span.untermstring {
  color: #b20000;
}

span.syscmd {
  color: #b28c00;
}

span.typesection {
  color: #a0522d;
}

/* ------------------------------
   Math
------------------------------ */

/*
MATLAB often converts LaTeX to img.equation with the original TeX in the alt
attribute. The XSL below emits the alt text directly so MathJax can render it.
This class should be inline; MathJax itself will handle $$...$$ display math.
*/
.math {
  display: inline;
}

/* MathJax display equations. */
mjx-container[display="true"] {
  margin: 1.2em 0 !important;
  overflow-x: auto;
  overflow-y: hidden;
}

/* ------------------------------
   Images and figures
------------------------------ */

img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 1.5em auto;
  border: none;
}

/* ------------------------------
   Tables
------------------------------ */

table {
  margin: 1.5em 0;
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95em;
}

table th {
  background: #f0f0f0;
  font-weight: bold;
}

table th,
table td {
  padding: 0.6em 0.8em;
  border: 1px solid #d6d4d4;
  text-align: left;
  vertical-align: top;
}

/* ------------------------------
   Contents
------------------------------ */

.contents {
  margin: 2em 0 3em 0;
  padding: 1.25em 1.5em;
  background: #f7f4ed;
  border: 1px solid #e2ded3;
  border-radius: 4px;
}

.contents h2 {
  margin-top: 0;
}

.contents ul {
  margin-bottom: 0;
}

/* ------------------------------
   Footer
------------------------------ */

.footer {
  margin-top: 4em;
  padding-top: 1em;
  border-top: 1px solid #ddd;
  color: #777;
  font-size: 0.8em;
  font-style: italic;
}

.footer p {
  margin: 0;
}

.footer a {
  color: #777;
}

.footer a:hover {
  color: #777;
  text-decoration: underline;
}

.footer a:visited {
  color: #777;
}

/* ------------------------------
   Responsive layout
------------------------------ */

@media screen and (max-width: 900px) {
  .content {
    max-width: none;
    margin: 0;
    padding: 36px 28px 64px 28px;
    border-radius: 0;
  }

  html body {
    font-size: 17px;
  }
}

@media screen and (max-width: 520px) {
  .content {
    padding: 28px 20px 56px 20px;
  }

  html body {
    font-size: 16px;
  }

  h1 {
    font-size: 2em;
  }

  .content > h1:first-of-type {
    font-size: 2.2em;
  }

  h2 {
    font-size: 1.35em;
  }
}

/* ------------------------------
   Print layout
------------------------------ */

@media print {
  html,
  html body {
    background: white;
  }

  html body {
    font-size: 12pt;
    line-height: 1.5;
  }

  .content {
    max-width: none;
    margin: 0;
    padding: 0;
    box-shadow: none;
    border-radius: 0;
    background: white;
  }

  h1 {
    page-break-before: always;
  }

  h1:first-child {
    page-break-before: avoid;
  }

  h2,
  h3 {
    page-break-after: avoid;
  }

  pre.codeinput,
  pre.codeoutput {
    white-space: pre-wrap;
    word-wrap: break-word;
    width: 100%;
  }

  a {
    color: black;
  }
}

    </style>
  </xsl:template>


  <!-- Header -->
  <xsl:template name="header">
  </xsl:template>


  <!-- Footer -->
  <xsl:template name="footer">
    <p class="footer">
      <xsl:value-of select="copyright"/>
      <br/>
      <a href="https://www.mathworks.com/products/matlab/">
        <xsl:text>Published with MATLAB</xsl:text>
        <xsl:text> </xsl:text>
        <xsl:text>R</xsl:text>
        <xsl:value-of select="release"/>
      </a>
      <br/>
    </p>
  </xsl:template>


  <!-- Contents -->
  <xsl:template name="contents">
    <xsl:param name="body-cells"/>
    <div class="contents">
      <h2>Contents</h2>
      <ul>
        <xsl:for-each select="$body-cells">
          <xsl:if test="./steptitle">
            <li>
              <a>
                <xsl:attribute name="href">
                  <xsl:text>#</xsl:text>
                  <xsl:value-of select="position()"/>
                </xsl:attribute>
                <xsl:apply-templates select="steptitle"/>
              </a>
            </li>
          </xsl:if>
        </xsl:for-each>
      </ul>
    </div>
  </xsl:template>


  <!-- HTML tags in text sections -->

  <xsl:template match="p">
    <p>
      <xsl:apply-templates/>
    </p>
  </xsl:template>

  <xsl:template match="ul">
    <ul>
      <xsl:apply-templates/>
    </ul>
  </xsl:template>

  <xsl:template match="ol">
    <ol>
      <xsl:apply-templates/>
    </ol>
  </xsl:template>

  <xsl:template match="li">
    <li>
      <xsl:apply-templates/>
    </li>
  </xsl:template>

  <xsl:template match="pre">
    <xsl:choose>
      <xsl:when test="@class='error'">
        <pre class="error">
          <xsl:apply-templates/>
        </pre>
      </xsl:when>
      <xsl:otherwise>
        <pre>
          <xsl:apply-templates/>
        </pre>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="b">
    <b>
      <xsl:apply-templates/>
    </b>
  </xsl:template>

  <xsl:template match="i">
    <i>
      <xsl:apply-templates/>
    </i>
  </xsl:template>

  <xsl:template match="tt">
    <tt>
      <xsl:apply-templates/>
    </tt>
  </xsl:template>

  <xsl:template match="a">
    <a>
      <xsl:attribute name="href">
        <xsl:value-of select="@href"/>
      </xsl:attribute>
      <xsl:apply-templates/>
    </a>
  </xsl:template>

  <xsl:template match="html">
    <xsl:value-of select="@text" disable-output-escaping="yes"/>
  </xsl:template>

  <!-- Suppress MATLAB's native LaTeX node if present. -->
  <xsl:template match="latex"/>


  <!-- Detecting M-code in comments -->
  <xsl:template match="text/mcode-xmlized">
    <pre class="language-matlab">
      <xsl:apply-templates/>
      <xsl:text>
</xsl:text>
    </pre>
  </xsl:template>


  <!-- Code input and output -->

  <xsl:template match="mcode-xmlized">
    <pre class="codeinput">
      <xsl:apply-templates/>
      <xsl:text>
</xsl:text>
    </pre>
  </xsl:template>

  <xsl:template match="mcodeoutput">
    <xsl:choose>
      <xsl:when test="concat(substring(.,0,7),substring(.,string-length(.)-7,7))='&lt;html&gt;&lt;/html&gt;'">
        <xsl:value-of select="substring(.,7,string-length(.)-14)" disable-output-escaping="yes"/>
      </xsl:when>
      <xsl:otherwise>
        <pre>
          <xsl:attribute name="class">
            <xsl:value-of select="@class"/>
          </xsl:attribute>
          <xsl:apply-templates/>
        </pre>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>


  <!-- Figure, model snapshots, and equations -->

  <!--
    Key math fix:
    MATLAB publish may turn both inline and display LaTeX into img.equation.
    The original TeX is stored in @alt, usually including its $...$ or $$...$$.
    So we emit @alt directly and let MathJax render it.
    Do NOT wrap this in extra dollar signs.
  -->
  <xsl:template match="img[@class='equation']">
    <span class="math">
      <xsl:value-of select="@alt"/>
    </span>
  </xsl:template>

  <xsl:template match="img">
    <img>
      <xsl:attribute name="src">
        <xsl:value-of select="@src"/>
      </xsl:attribute>

      <xsl:if test="@width or @height">
        <xsl:attribute name="style">
          <xsl:if test="@width">
            <xsl:text>width:</xsl:text>
            <xsl:value-of select="@width"/>
            <xsl:text>;</xsl:text>
          </xsl:if>
          <xsl:if test="@height">
            <xsl:text>height:</xsl:text>
            <xsl:value-of select="@height"/>
            <xsl:text>;</xsl:text>
          </xsl:if>
        </xsl:attribute>
      </xsl:if>

      <xsl:attribute name="alt">
        <xsl:value-of select="@alt"/>
      </xsl:attribute>
    </img>
  </xsl:template>


  <!-- Stash original code in HTML for easy slurping later. -->

  <xsl:template match="originalCode">
    <xsl:variable name="xcomment">
      <xsl:call-template name="globalReplace">
        <xsl:with-param name="outputString" select="."/>
        <xsl:with-param name="target" select="'--'"/>
        <xsl:with-param name="replacement" select="'REPLACE_WITH_DASH_DASH'"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:comment>
##### SOURCE BEGIN #####
<xsl:value-of select="$xcomment"/>
##### SOURCE END #####
    </xsl:comment>
  </xsl:template>


  <!-- Colors for syntax-highlighted input code -->

  <xsl:template match="mwsh:code">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="mwsh:keywords">
    <span class="keyword">
      <xsl:value-of select="."/>
    </span>
  </xsl:template>

  <xsl:template match="mwsh:strings">
    <span class="string">
      <xsl:value-of select="."/>
    </span>
  </xsl:template>

  <xsl:template match="mwsh:comments">
    <span class="comment">
      <xsl:value-of select="."/>
    </span>
  </xsl:template>

  <xsl:template match="mwsh:unterminated_strings">
    <span class="untermstring">
      <xsl:value-of select="."/>
    </span>
  </xsl:template>

  <xsl:template match="mwsh:system_commands">
    <span class="syscmd">
      <xsl:value-of select="."/>
    </span>
  </xsl:template>

  <xsl:template match="mwsh:type_section">
    <span class="typesection">
      <xsl:value-of select="."/>
    </span>
  </xsl:template>


  <!-- Footer information -->

  <xsl:template match="copyright">
    <xsl:value-of select="."/>
  </xsl:template>

  <xsl:template match="revision">
    <xsl:value-of select="."/>
  </xsl:template>


  <!-- Search and replace -->
  <!-- From http://www.xml.com/lpt/a/2002/06/05/transforming.html -->

  <xsl:template name="globalReplace">
    <xsl:param name="outputString"/>
    <xsl:param name="target"/>
    <xsl:param name="replacement"/>

    <xsl:choose>
      <xsl:when test="contains($outputString,$target)">
        <xsl:value-of select="concat(substring-before($outputString,$target),$replacement)"/>
        <xsl:call-template name="globalReplace">
          <xsl:with-param name="outputString" select="substring-after($outputString,$target)"/>
          <xsl:with-param name="target" select="$target"/>
          <xsl:with-param name="replacement" select="$replacement"/>
        </xsl:call-template>
      </xsl:when>

      <xsl:otherwise>
        <xsl:value-of select="$outputString"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>
