\documentclass[11pt,a4paper]{article} \usepackage{array} \usepackage{tabularx} \usepackage{float} \usepackage{ltmermaid} \usepackage[hidelinks]{hyperref} \usepackage{bxghost} \usepackage{listings} \usepackage{xcolor} \lstset{ basicstyle={\ttfamily}, identifierstyle={\small}, commentstyle={\small\itshape}, keywordstyle={\small\bfseries}, ndkeywordstyle={\small}, stringstyle={\small\ttfamily}, frame={tb}, breaklines=true, columns=[l]{fullflexible}, numbers=left, xrightmargin=0pt, xleftmargin=1.5em, numberstyle={\scriptsize}, stepnumber=1, numbersep=0.5em, lineskip=-0.5ex } \makeatletter \def\m@syu@space@char{^^`} \def\m@syu@string#1{% \@tfor\m@syu@member:=#1\do{% \ifx\m@syu@member\m@syu@space@char \textvisiblespace \else \ifx\m@syu@member\empty \textvisiblespace \else\m@syu@member\fi \fi}% } \def\m@syu@removespace#1{% \def\m@syu@removedspace{}% \@tfor\m@syu@member:=#1\do{% \ifx\m@syu@member\empty \edef\m@syu@removedspace{\m@syu@removedspace\m@syu@member\m@syu@space@char}% \else \edef\m@syu@removedspace{\m@syu@removedspace\m@syu@member}% \fi}% } \newcommand{\cmd}[2][\texttt]{\eghostguarded{#1{\symbol{92}\m@syu@string{#2}}}} \makeatother \newcolumntype{L}{>{\raggedright\arraybackslash}X} \title{The \texttt{ltmermaid} package} \author{安藤 遼哉(Ryoya Ando)\\\url{https://ryoya9826.github.io/}} \date{\today} \begin{document} \maketitle \begin{abstract} \noindent The \texttt{ltmermaid} package renders Mermaid diagrams at \LaTeXe{} compile time when using \textbf{LuaLaTeX} and embeds them in the PDF. Rendering uses external tools such as the Mermaid CLI, so \textbf{shell escape} (\verb|-shell-escape|) is required. The machine that runs \texttt{lualatex} must have a working \textbf{Node.js} installation, \texttt{mmdc} (or \texttt{npx}), and headless Chromium for the CLI. \end{abstract} \section{Requirements} \noindent \begin{tabularx}{\textwidth}{@{}>{\raggedright\arraybackslash}p{0.22\textwidth}L@{}} \hline \textbf{Item} & \textbf{Requirement} \\ \hline \TeX{} engine & LuaLaTeX (\texttt{lualatex}). \\ Format & \LaTeXe. \\ Shell escape & \texttt{lualatex -shell-escape} (the package invokes the CLI via \texttt{os.execute}). \\ External tool & Mermaid CLI (\texttt{mmdc}). \\ \hline \end{tabularx} \medskip If the Mermaid CLI is missing from the environment, \texttt{ltmermaid} does \textbf{not} auto-install \texttt{mmdc} or similar. A typical setup uses \textbf{Node.js} with \texttt{npm} (or \texttt{npx}). If you pass a command that includes \textbf{\texttt{npx -y}} via the package option \texttt{Renderer}---for example \texttt{npx -y @mermaid-js/mermaid-cli \ldots}---then \texttt{npx} may fetch and install packages as needed (\textbf{network access} may be required). When you run \texttt{lualatex}, unless the \texttt{Renderer} option points to another command, the default renderer \texttt{mmdc} must be visible in the same environment (if you set \texttt{Renderer}, that command must be visible instead). The Mermaid CLI depends on headless Chromium (Puppeteer); see the Mermaid CLI documentation for details. \section{License and source} \noindent Distributed under the \LaTeX{} Project Public License (LPPL), version 1.3c or later.\\ Source and issues: \url{https://github.com/ryoya9826/ltMermaid} \section{Usage} \subsection{Minimal document} \begin{lstlisting} \documentclass{article} \usepackage{ltmermaid} \begin{document} \begin{mermaid} flowchart LR A --> B \end{mermaid} \end{document} \end{lstlisting} Compile with: \begin{lstlisting}[language=bash] lualatex -shell-escape yourfile.tex \end{lstlisting} \subsection{Layout adjustments (optional)} By default, included graphics are scaled with \texttt{adjustbox}. Example: \begin{lstlisting} \MermaidAdjustBoxOpts{max width=0.8\linewidth,center} \MermaidAdjustBoxOpts{max width=0.9\linewidth,center,valign=T} \end{lstlisting} \subsection{Beamer} The package works with the \texttt{beamer} class. Any frame that contains a \texttt{mermaid} environment must use the \texttt{fragile} option (the environment relies on \texttt{fancyvrb}), for example \verb|\begin{frame}[fragile]{Diagram}|. \begin{lstlisting} \documentclass{beamer} \usepackage{ltmermaid} \begin{document} \begin{frame}[fragile]{Mermaid} \begin{mermaid} flowchart LR A --> B \end{mermaid} \end{frame} \end{document} \end{lstlisting} \section{Package options (optional)} {\small \begin{itemize} \item \textbf{\texttt{Renderer}}: Prefix for the renderer command. If omitted, the default is \texttt{mmdc}. You can set it explicitly, for example \texttt{npx -y @mermaid-js/mermaid-cli}. \end{itemize} \par} \section{User macros} {\small \begin{itemize} \item \textbf{\cmd{MermaidRendererOptions}\texttt{\{...\}}:} Extra CLI arguments before \texttt{-i} / \texttt{-o} (merged after the built-in \texttt{-f} when PDF fit is enabled). \item \textbf{\cmd{MermaidNoPdfFit}:} Disables \texttt{-f} / \texttt{--pdfFit} for \texttt{mmdc} (by default this is \emph{on}). \item \textbf{\cmd{MermaidAdjustBoxOpts}\texttt{\{...\}}:} Full \texttt{adjustbox} key list around \cmd{includegraphics} (default \texttt{max width=0.9}\cmd{linewidth}\texttt{,center}). \item \textbf{\cmd{MermaidGraphicsOpts}\texttt{\{...\}}:} Extra keys for \cmd{includegraphics} (e.g.\ rotation, \texttt{trim}); width is usually set with \cmd{MermaidAdjustBoxOpts}. \item \textbf{\cmd{mermaidfile}\texttt{[]\{filename\}}:} Render a Mermaid diagram from an external file (\texttt{.mmd}) instead of inline code. The diagram is rendered and included just like the \texttt{mermaid} environment, and an optional argument may be used to pass keys directly to \cmd{includegraphics}. \end{itemize} \par} \subsection{Including diagrams from files} You can use \cmd{mermaidfile}\texttt{[]\{filename\}} to render a Mermaid diagram from an external file. Example: \begin{lstlisting} \mermaidfile[width=0.8\linewidth]{diagram-001.mmd} \end{lstlisting} The optional argument is forwarded directly to \cmd{includegraphics}, so valid keys include \texttt{width}, \texttt{height}, \texttt{angle}, \texttt{trim}, \texttt{keepaspectratio}, and similar graphics options. \section{Output files} Intermediate \texttt{.mmd} and \texttt{.pdf} files are written under the \texttt{mermaid/} directory relative to the directory where compilation runs. With \texttt{-output-directory}, they are written under \texttt{mermaid/} inside the directory indicated by the environment variable \texttt{TEXMF\_OUTPUT\_DIRECTORY}. \section{Examples} \textbf{Left:} source for the \texttt{mermaid} environment as typed. \textbf{Right:} rendered diagram. \begin{figure}[H] \begin{minipage}[t]{0.42\textwidth} \vspace{0pt} \begin{lstlisting}[basicstyle=\footnotesize\ttfamily] \begin{mermaid} flowchart TB subgraph client["Client tier"] WEB["Browser / SPA"] CLI["CLI / batch"] end subgraph edge["Edge"] GW{{API Gateway}} end subgraph svc["Services"] AUTH["Auth"] API["Business API"] WORK["Workers"] end subgraph store["Data"] DB[("PostgreSQL")] CACHE[("Redis")] QUEUE["Job queue"] end WEB --> GW CLI --> GW GW --> AUTH GW --> API API --> WORK API --> DB API --> CACHE WORK --> QUEUE WORK --> DB \end{mermaid} \end{lstlisting} \end{minipage}% \hfill \begin{minipage}[t]{0.54\textwidth} \vspace{0pt}\centering \begin{mermaid} flowchart TB subgraph client["Client tier"] WEB["Browser / SPA"] CLI["CLI / batch"] end subgraph edge["Edge"] GW{{API Gateway}} end subgraph svc["Services"] AUTH["Auth"] API["Business API"] WORK["Workers"] end subgraph store["Data"] DB[("PostgreSQL")] CACHE[("Redis")] QUEUE["Job queue"] end WEB --> GW CLI --> GW GW --> AUTH GW --> API API --> WORK API --> DB API --> CACHE WORK --> QUEUE WORK --> DB \end{mermaid} \end{minipage} \caption{Layered architecture (subgraphs and node shapes)} \end{figure} \begin{figure}[H] \begin{minipage}[t]{0.42\textwidth} \vspace{0pt} \begin{lstlisting}[basicstyle=\footnotesize\ttfamily] \begin{mermaid} sequenceDiagram autonumber actor U as User participant B as Browser participant A as Auth API participant S as Business API participant D as DB U->>B: Log in B->>+A: POST /token A->>D: Verify user D-->>A: Row A-->>-B: JWT B->>+S: GET /orders (Bearer) S->>A: Validate token A-->>S: Claims S->>D: SELECT D-->>S: Rows S-->>-B: 200 JSON B-->>U: Show list \end{mermaid} \end{lstlisting} \end{minipage}% \hfill \begin{minipage}[t]{0.54\textwidth} \vspace{0pt}\centering \begin{mermaid} sequenceDiagram autonumber actor U as User participant B as Browser participant A as Auth API participant S as Business API participant D as DB U->>B: Log in B->>+A: POST /token A->>D: Verify user D-->>A: Row A-->>-B: JWT B->>+S: GET /orders (Bearer) S->>A: Validate token A-->>S: Claims S->>D: SELECT D-->>S: Rows S-->>-B: 200 JSON B-->>U: Show list \end{mermaid} \end{minipage} \caption{Sequence diagram (autonumber, async arrows, multiple participants)} \end{figure} \begin{figure}[H] \begin{minipage}[t]{0.42\textwidth} \vspace{0pt} \begin{lstlisting}[basicstyle=\footnotesize\ttfamily] \begin{mermaid} stateDiagram-v2 [*] --> Draft: Create Draft --> Review: Submit Review --> Draft: Send back Review --> Approved: Approve Approved --> Published: Publish Published --> Archived: Close Review --> Rejected: Reject Rejected --> [*] Archived --> [*] \end{mermaid} \end{lstlisting} \end{minipage}% \hfill \begin{minipage}[t]{0.54\textwidth} \vspace{0pt}\centering \begin{mermaid} stateDiagram-v2 [*] --> Draft: Create Draft --> Review: Submit Review --> Draft: Send back Review --> Approved: Approve Approved --> Published: Publish Published --> Archived: Close Review --> Rejected: Reject Rejected --> [*] Archived --> [*] \end{mermaid} \end{minipage} \caption{State machine (\texttt{stateDiagram-v2})} \end{figure} \section{Version history} \begin{description} \item[Version 1.0c (2026-05-06)] Various bug fixes. \item[Version 1.0b (2026-04-29)] Added \cmd{mermaidfile} support, Makefile build/test targets, and \texttt{l3build} regression testing. \item[Version 1.0a (2026-04-20)] Renamed sample documents. \item[Version 1.0 (2026-04-16)] Stable release. \item[Version 0.2 (2026-04-13)] Removed \texttt{MERMAID\_MMDC} and \texttt{MERMAID\_MMDC\_OPTIONS}. \item[Version 0.1 (2026-04-08)] Initial release. \end{description} \end{document}