Skip to content
Closed

Mermaid #2178

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions doc/guide/author/topics.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3143,6 +3143,62 @@ displayed line, and there are no <c>\\</c>s. Use <c>\amp</c> to mark the alignm

<p>Note the necessity of using the <c>pretext</c> script (<xref ref="pretext-script"/>) to independently invoke Sage, no matter what sort of output is being created for your document.</p>
</subsubsection>

<subsubsection xml:id="topic-mermaid">
<title>Mermaid</title>

<p><url href="https://mermaid.js.org/" visual="mermaid.js.org">Mermaid</url> is a Markdown-inspired tool for authoring various kinds of diagrams. One kind of diagram - a git commit visualization - is shown below. For a full listing of diagram types, see the <url href="https://mermaid.js.org/intro/#diagram-types">Mermaid Documentation</url>. The <url href="https://mermaid.live/" visual="mermaid.live">Mermaid live editor</url>is a great tool for testing the syntax of your mermaid diagrams.</p>

<p>In PreTeXt, you can specify a Mermaid theme via <attr>common/mermaid/@theme</attr></p>

<p>To author a Mermaid diagram, use a <tag>image</tag> that contains a <tag>mermaid</tag> element.</p>

<pre>
&lt;figure xml:id="figure-mermaid-git"&gt;
&lt;caption&gt;Mermaid Git Diagram&gt;/caption&gt;
&lt;image xml:id="mermaid-git-image"&gt;
&lt;mermaid&gt;
---
title: Example Git diagram
---
gitGraph
commit
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
commit
&lt;/mermaid&gt;
&lt;/image&gt;
&lt;/figure&gt;
</pre>

<figure xml:id="figure-mermaid-git">
<caption>Mermaid Git Diagram</caption>
<image xml:id="mermaid-git-image">
<mermaid>
---
title: Example Git diagram
---
gitGraph
commit
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
commit
</mermaid>
</image>
</figure>
</subsubsection>
</subsection>

<subsection>
Expand Down
14 changes: 14 additions & 0 deletions doc/guide/publisher/publication-file.xml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,20 @@
<p>In the text itself avoid obscure characters or symbols, and do not use any markup. Keep it simple. When used with <latex/> output the scharacters <c>\\</c> will survive in the text to create multiple lines of text in the watermark. This feature is implemented for <latex/> and <init>HTML</init> output. See <xref ref="watermarks"/> for more detail and an example.</p>
</subsection>

<subsection xml:id="common-mermaid">
<title>Mermaid</title>
<idx><h>Mermaid themes</h></idx>

<p>
Various themes are available for Mermaid diagrams. To use a theme, set
<cd>
<cline>/publication/common/mermaid/@theme</cline>
</cd>
with a value of the theme name. The default theme is <c>default</c>.
See <xref ref="topic-mermaid"/> for more information on Mermaid diagrams.
</p>
</subsection>

<subsection xml:id="common-qrcode-image">
<title>QR code image</title>
<idx><h>common option</h><h>qrcode</h></idx>
Expand Down
88 changes: 88 additions & 0 deletions examples/sample-article/sample-article.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3413,6 +3413,94 @@ along with MathBook XML. If not, see <http://www.gnu.org/licenses/>.
</figure>
</subsection>

<subsection xml:id="graphics-mermaid">
<title>Mermaid Diagrams</title>
<idx><h>Mermaid diagrams</h></idx>

<p><url href="https://mermaid.js.org/" visual="mermaid.js.org">Mermaid</url> is a Markdown-inspired tool for authoring various kinds of diagrams. Below, three of the available diagram types are demonstrated. For a full listing of diagram types, see the <url href="https://mermaid.js.org/intro/#diagram-types">Mermaid Documentation</url>. The <url href="https://mermaid.live/" visual="mermaid.live">Mermaid live editor</url>is a great tool for testing the syntax of your mermaid diagrams.</p>

<p>In PreTeXt, you can specify a Mermaid theme via <attr>common/mermaid/@theme</attr></p>

<figure xml:id="figure-mermaid-git">
<caption>Mermaid Git Diagram</caption>
<image xml:id="mermaid-git-image">
<shortdescription>
A git diagram in Mermaid
</shortdescription>
<mermaid>
---
title: Example Git diagram
---
gitGraph
commit
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
commit
</mermaid>
</image>
</figure>

<figure xml:id="figure-mermaid-class">
<caption>Mermaid Class Diagram</caption>
<image xml:id="mermaid-class-image">
<shortdescription>
A class diagram in Mermaid
</shortdescription>
<mermaid>
classDiagram
Animal &lt;|-- Duck
Animal &lt;-- Fish
Animal &lt;|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
</mermaid>
</image>
</figure>

<figure xml:id="figure-mermaid-sequence">
<caption>Mermaid Seuqnece Diagram</caption>
<image xml:id="mermaid-sequence-image">
<shortdescription>
A sequence diagram in Mermaid
</shortdescription>
<mermaid>
sequenceDiagram
participant Alice
participant Bob
Alice->>John: Hello John, how are you?
loop HealthCheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts &lt;br/>prevail!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
</mermaid>
</image>
</figure>
</subsection>

<subsection>
<title>Sage Plots</title>
<idx><h>Sage plots</h></idx>
Expand Down
1 change: 1 addition & 0 deletions pretext/pretext.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pdflatex = pdflatex
xelatex = xelatex
pdfsvg = pdf2svg
asy = asy
mermaid = mmdc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somehow I missed that part of the PR, great!

sage = sage
pdfpng = convert
pdfeps = pdftops
Expand Down
64 changes: 64 additions & 0 deletions pretext/pretext.py
Original file line number Diff line number Diff line change
Expand Up @@ -2056,6 +2056,70 @@ def qrcode(xml_source, pub_file, stringparams, xmlid_root, dest_dir):
log.info("QR code creation complete")


#####################################
#
# Mermaid images
#
#####################################

def mermaid_images(
xml_source, pub_file, stringparams, xmlid_root, dest_dir
):
msg = 'converting Mermaid diagrams from {} to png graphics for placement in {}'
log.info(msg.format(xml_source, dest_dir))

tmp_dir = get_temporary_directory()
log.debug("temporary directory: {}".format(tmp_dir))
ptx_xsl_dir = get_ptx_xsl_path()
extraction_xslt = os.path.join(ptx_xsl_dir, "extract-mermaid.xsl")

# support publisher file, subtree argument
if pub_file:
stringparams["publisher"] = pub_file
if xmlid_root:
stringparams["subtree"] = xmlid_root

log.info("extracting Mermaid diagrams from {}".format(xml_source))
log.info(
"string parameters passed to extraction stylesheet: {}".format(stringparams)
)
#generate mmd files with markdown to be converted to png
xsltproc(extraction_xslt, xml_source, None, tmp_dir, stringparams)

#Need a prettier way to get set value from pub file...
mermaid_theme = "default"
if pub_file:
pub_tree = ET.parse(pub_file)
mmd_elt = pub_tree.xpath("/publication/common/mermaid")
if mmd_elt:
attrs = mmd_elt[0].attrib
if "theme" in attrs:
mermaid_theme = mmd_elt[0].attrib['theme']

import glob
# Resulting *.mmd files are in tmp_dir, switch there to work
with working_directory(tmp_dir):
mmd_executable_cmd = get_executable_cmd("mermaid")
log.debug("Mermaid executable command: {}".format(mmd_executable_cmd))
for mmddiagram in glob.glob(os.path.join(tmp_dir, "*.mmd")):
filebase, _ = os.path.splitext(mmddiagram)
versions = [
{"name":"-color", "opts":["-s", "4", "-t", mermaid_theme]},
{"name":"-bw", "opts":["-s", "4", "-t", "neutral"]}
]
for version in versions:
mmdout = "{}.{}".format(filebase + version['name'], 'png')
mmd_cmd = mmd_executable_cmd + ["-i", mmddiagram, "-o", mmdout] + version['opts']
log.debug("mermaid conversion {}".format(" ".join(mmd_cmd)))
subprocess.call(mmd_cmd, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
if os.path.exists(mmdout):
shutil.copy2(mmdout, dest_dir)
else:
msg = [
"the Mermaid output {} was not built".format(mmdout),
]
log.warning("\n".join(msg))

#####################################
#
# Interactive preview screenshotting
Expand Down
60 changes: 60 additions & 0 deletions xsl/extract-mermaid.xsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version='1.0'?>

<!--********************************************************************
Copyright 2014-2016 Robert A. Beezer

This file is part of PreTeXt.

PreTeXt is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 or version 3 of the
License (at your option).

PreTeXt is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************-->

<!-- This stylesheet locates video/@youtube elements and -->
<!-- prepares a Python dictionary necessary to extract a -->
<!-- thumbnail for each video from the YouTube servers -->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:exsl="http://exslt.org/common"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="exsl"
>

<!-- Get internal ID's for filenames, etc -->
<!-- Standard conversion groundwork -->
<xsl:import href="./publisher-variables.xsl"/>
<xsl:import href="./pretext-assembly.xsl"/>
<xsl:import href="./pretext-common.xsl"/>

<!-- Get a "subtree" xml:id value -->
<!-- Then walk the XML source tree -->
<!-- applying specializations below -->
<xsl:import href="./extract-identity.xsl" />

<xsl:output method="text" encoding="UTF-8"/>

<xsl:variable name="mermaid-extracting"><xsl:value-of select="true()"/></xsl:variable>

<xsl:template match="image[mermaid]" mode="extraction">
<xsl:variable name="filebase">
<xsl:apply-templates select="." mode="assembly-id"/>
</xsl:variable>

<exsl:document href="{$filebase}.mmd" method="text">
<xsl:call-template name="sanitize-text">
<xsl:with-param name="text" select="./mermaid" />
</xsl:call-template>
</exsl:document>
</xsl:template>

</xsl:stylesheet>
44 changes: 43 additions & 1 deletion xsl/pretext-assembly.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -1224,7 +1224,7 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
<!-- we want the stylesheet to be independent, and the template is -->
<!-- also applied here. -->

<xsl:template match="audio|video|interactive" mode="assembly-id">
<xsl:template match="audio|video|interactive|image" mode="assembly-id">
<xsl:value-of select="@assembly-id"/>
</xsl:template>

Expand Down Expand Up @@ -2269,6 +2269,48 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.

<!-- Static versions of Audio, Video, Interactives -->

<!-- This variable will be overriden during an extraction used to write image files -->
<xsl:variable name="mermaid-extracting"><xsl:value-of select="false()"/></xsl:variable>
<xsl:template match="image[mermaid]" mode="representations">
<xsl:choose>
<xsl:when test="$mermaid-extracting = 'false'">
<!-- Generating document -->
<xsl:choose>
<xsl:when test="$exercise-style = 'dynamic'">
<!-- interactive target -->
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="representations"/>
</xsl:copy>
</xsl:when>
<xsl:when test="$exercise-style = 'static'">
<!-- static target -->
<image>
<xsl:attribute name="pi:generated">
<xsl:text>mermaid/</xsl:text>
<xsl:apply-templates select="." mode="assembly-id"/>
<xsl:choose>
<!-- latex-print will be B&W target -->
<xsl:when test="$b-latex-print">
<xsl:text>-bw.png</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>-color.png</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</image>
</xsl:when>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<!-- Extracting Mermaid -->
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="representations"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<!-- Form a PreTeXt side-by-side with an image, a QR code and links -->

<xsl:template match="audio|video|interactive[not(static)]" mode="representations">
Expand Down
Loading