@cristianormazabal/triton-latex 0.1.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/README.md +186 -0
- package/dist/cli.cjs +41543 -0
- package/dist/cli.cjs.map +7 -0
- package/package.json +52 -0
- package/triton.sty +198 -0
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cristianormazabal/triton-latex",
|
|
3
|
+
"description": "LaTeX integration for Triton — render diagrams to vector PDF for \\includegraphics.",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"latex",
|
|
9
|
+
"pdf",
|
|
10
|
+
"triton",
|
|
11
|
+
"diagrams",
|
|
12
|
+
"svg-to-pdf",
|
|
13
|
+
"mermaid"
|
|
14
|
+
],
|
|
15
|
+
"bin": {
|
|
16
|
+
"triton-latex": "./dist/cli.cjs"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=20"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"triton.sty"
|
|
24
|
+
],
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/ormasoftchile/triton.git",
|
|
28
|
+
"directory": "latex"
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://github.com/ormasoftchile/triton",
|
|
34
|
+
"bugs": "https://github.com/ormasoftchile/triton/issues",
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "node esbuild.mjs",
|
|
37
|
+
"prepublishOnly": "npm run build",
|
|
38
|
+
"render": "node dist/cli.cjs render",
|
|
39
|
+
"render-dir": "node dist/cli.cjs render-dir",
|
|
40
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"pdfkit": "^0.15.0",
|
|
44
|
+
"svg-to-pdfkit": "^0.1.8"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^22.0.0",
|
|
48
|
+
"@types/pdfkit": "^0.13.4",
|
|
49
|
+
"esbuild": "^0.24.0",
|
|
50
|
+
"typescript": "^5.8.3"
|
|
51
|
+
}
|
|
52
|
+
}
|
package/triton.sty
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
% triton.sty — author Triton diagrams directly in LaTeX (like TikZ), or include
|
|
2
|
+
% precompiled vector PDFs as an Overleaf fallback.
|
|
3
|
+
%
|
|
4
|
+
% ── HEADLINE: inline authoring ──────────────────────────────────────────────
|
|
5
|
+
% Put the diagram SOURCE straight in your .tex and it renders inline:
|
|
6
|
+
%
|
|
7
|
+
% \documentclass{article}
|
|
8
|
+
% \usepackage{triton}
|
|
9
|
+
% \begin{document}
|
|
10
|
+
% \begin{triton}
|
|
11
|
+
% flowchart LR
|
|
12
|
+
% A[Start] --> B{Choice}
|
|
13
|
+
% B --> C[End]
|
|
14
|
+
% \end{triton}
|
|
15
|
+
% \end{document}
|
|
16
|
+
%
|
|
17
|
+
% Compile WITH shell-escape (this is required for the inline environment):
|
|
18
|
+
% pdflatex -shell-escape file.tex
|
|
19
|
+
% lualatex -shell-escape file.tex
|
|
20
|
+
% tectonic -Z shell-escape -Z shell-escape-cwd=. file.tex
|
|
21
|
+
%
|
|
22
|
+
% How it works (the minted model): the `triton` environment captures its body
|
|
23
|
+
% VERBATIM, writes it to a temp file, content-hashes the source (so a diagram is
|
|
24
|
+
% only re-rendered when it changes), shells out via \write18 to the @triton/latex
|
|
25
|
+
% CLI to produce a vector PDF in a cache directory, then \includegraphics it.
|
|
26
|
+
%
|
|
27
|
+
% ── FALLBACK: precompiled include (Overleaf / no shell-escape) ──────────────
|
|
28
|
+
% Overleaf disallows arbitrary shell-escape. There, precompile the diagrams to
|
|
29
|
+
% PDF (see the @triton/latex CLI `render-dir`) and drop them in by NAME — this is
|
|
30
|
+
% engine-agnostic and needs no Node/Triton toolchain on the LaTeX side:
|
|
31
|
+
%
|
|
32
|
+
% \tritondir{figures} % where the *.pdf live (default: triton-figures)
|
|
33
|
+
% \triton{flowchart} % \includegraphics the precompiled figures/flowchart.pdf
|
|
34
|
+
% \triton[width=0.6\linewidth]{avl}
|
|
35
|
+
%
|
|
36
|
+
% \triton{<name>} is BOTH the precompiled-include command AND the name of the
|
|
37
|
+
% inline environment — LaTeX would normally forbid that, so the package dispatches
|
|
38
|
+
% on \@currenvir: inside \begin{triton}…\end{triton} it authors inline; used as a
|
|
39
|
+
% bare command \triton[opts]{name} it includes a precompiled PDF.
|
|
40
|
+
%
|
|
41
|
+
% ── Macro summary ───────────────────────────────────────────────────────────
|
|
42
|
+
% \begin{triton} … \end{triton} inline authoring (needs shell-escape)
|
|
43
|
+
% \tritonnext{opts} \includegraphics opts for the NEXT
|
|
44
|
+
% inline diagram only (per-diagram size)
|
|
45
|
+
% \tritoninline[opts]|… one line …| one-line inline source
|
|
46
|
+
% \triton[opts]{name} include precompiled <dir>/name.pdf
|
|
47
|
+
% \tritonfile[opts]{name} explicit alias of the include form
|
|
48
|
+
% \tritonfig[opts]{name}{caption} precompiled include in a figure
|
|
49
|
+
% \tritondir{path} precompiled-PDF directory
|
|
50
|
+
% \tritonsetup{opts} default \includegraphics options
|
|
51
|
+
% \tritoncli{cmd} CLI invocation (default: triton-latex)
|
|
52
|
+
% \tritontheme{name} theme preset for inline renders
|
|
53
|
+
% \tritonscale{n} scale passed to the CLI (default 1)
|
|
54
|
+
% \tritoncachedir{dir} render cache (default \jobname.triton-cache)
|
|
55
|
+
%
|
|
56
|
+
% NOTE on sizing: a verbatim environment cannot reliably take an inline optional
|
|
57
|
+
% argument (\begin{triton}[width=…] would swallow the diagram's first line), so
|
|
58
|
+
% per-diagram \includegraphics options are set just BEFORE the environment with
|
|
59
|
+
% \tritonnext{…}; \tritonsetup{…} sets the global default.
|
|
60
|
+
|
|
61
|
+
\NeedsTeXFormat{LaTeX2e}
|
|
62
|
+
\ProvidesPackage{triton}[2026/06/24 v0.2.0 Inline Triton diagram authoring in LaTeX]
|
|
63
|
+
|
|
64
|
+
\RequirePackage{graphicx}
|
|
65
|
+
\RequirePackage{fancyvrb} % verbatim body capture (VerbatimOut)
|
|
66
|
+
\RequirePackage{pdftexcmds} % \pdf@shellescape, \pdf@filemdfivesum (engine-agnostic)
|
|
67
|
+
|
|
68
|
+
% ── Shared default \includegraphics options ─────────────────────────────────
|
|
69
|
+
\def\triton@opts{width=\linewidth}
|
|
70
|
+
\newcommand{\tritonsetup}[1]{\def\triton@opts{#1}}
|
|
71
|
+
|
|
72
|
+
% ── Precompiled-PDF directory (fallback workflow) ───────────────────────────
|
|
73
|
+
\def\triton@dir{triton-figures}
|
|
74
|
+
\newcommand{\tritondir}[1]{\def\triton@dir{#1}}
|
|
75
|
+
|
|
76
|
+
% The precompiled-include behaviour, shared by \tritonfile and by the bare
|
|
77
|
+
% \triton[opts]{name} command form (dispatched below).
|
|
78
|
+
\newcommand{\triton@include}[2][\triton@opts]{%
|
|
79
|
+
\includegraphics[#1]{\triton@dir/#2.pdf}%
|
|
80
|
+
}
|
|
81
|
+
\let\tritonfile\triton@include
|
|
82
|
+
|
|
83
|
+
\newcommand{\tritonfig}[3][\triton@opts]{%
|
|
84
|
+
\begin{figure}[htbp]%
|
|
85
|
+
\centering
|
|
86
|
+
\triton@include[#1]{#2}%
|
|
87
|
+
\caption{#3}%
|
|
88
|
+
\end{figure}%
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
% ── Inline-render configuration ─────────────────────────────────────────────
|
|
92
|
+
\def\triton@cli{triton-latex}
|
|
93
|
+
\newcommand{\tritoncli}[1]{\def\triton@cli{#1}}
|
|
94
|
+
\def\triton@scale{1}
|
|
95
|
+
\newcommand{\tritonscale}[1]{\def\triton@scale{#1}}
|
|
96
|
+
\def\triton@themearg{}
|
|
97
|
+
\newcommand{\tritontheme}[1]{\def\triton@themearg{\space--theme #1}}
|
|
98
|
+
\def\triton@cachedir{\jobname.triton-cache}
|
|
99
|
+
\newcommand{\tritoncachedir}[1]{\def\triton@cachedir{#1}}
|
|
100
|
+
% Temp file the verbatim diagram source is written to before rendering. The
|
|
101
|
+
% input extension is irrelevant to the CLI's single-file `render' (the renderer
|
|
102
|
+
% auto-detects the diagram kind from the source header); only the .pdf OUTPUT
|
|
103
|
+
% extension matters.
|
|
104
|
+
\def\triton@tmpfile{\jobname.triton-src.triton}
|
|
105
|
+
|
|
106
|
+
% Per-diagram \includegraphics options for the NEXT inline render. Defaults to
|
|
107
|
+
% the global \triton@opts; \tritonnext{…} overrides it for the next diagram only.
|
|
108
|
+
% (A verbatim environment cannot reliably carry an inline optional argument like
|
|
109
|
+
% \begin{triton}[width=…] — peeking for the `[' tokenises the line break that
|
|
110
|
+
% fancyvrb needs to delimit the body — so per-diagram sizing is set just BEFORE
|
|
111
|
+
% the environment with \tritonnext instead.)
|
|
112
|
+
\newif\iftriton@nextset
|
|
113
|
+
\newcommand{\tritonnext}[1]{\def\triton@nextopts{#1}\triton@nextsettrue}
|
|
114
|
+
|
|
115
|
+
% Stream used by \tritoninline to write its verbatim argument to the temp file.
|
|
116
|
+
\newwrite\triton@inlinestream
|
|
117
|
+
|
|
118
|
+
% ── Core render step (shared by the environment and \tritoninline) ──────────
|
|
119
|
+
% Precondition: \triton@tmpfile holds the diagram source and \triton@curopts
|
|
120
|
+
% holds the \includegraphics options. Content-hash → cache → shell-out → include.
|
|
121
|
+
\newcommand{\triton@render}{%
|
|
122
|
+
\ifnum\pdf@shellescape=\@ne
|
|
123
|
+
\edef\triton@hash{\pdf@filemdfivesum{\triton@tmpfile}}%
|
|
124
|
+
\edef\triton@pdf{\triton@cachedir/\triton@hash.pdf}%
|
|
125
|
+
% Only render when this exact source has not been rendered before.
|
|
126
|
+
\IfFileExists{\triton@pdf}{}{%
|
|
127
|
+
\immediate\write18{\triton@cli\space render "\triton@tmpfile" -o
|
|
128
|
+
"\triton@pdf" --scale \triton@scale\triton@themearg}%
|
|
129
|
+
}%
|
|
130
|
+
\IfFileExists{\triton@pdf}{%
|
|
131
|
+
% \triton@curopts is a macro (e.g. width=\linewidth); graphicx mis-parses
|
|
132
|
+
% an unexpanded key-list macro in the optional argument ("Missing
|
|
133
|
+
% \endcsname" on the dimen), so expand it once into literal keys first.
|
|
134
|
+
\expandafter\includegraphics\expandafter[\triton@curopts]{\triton@pdf}%
|
|
135
|
+
}{%
|
|
136
|
+
\PackageError{triton}{Inline render produced no PDF}{%
|
|
137
|
+
The CLI did not create \triton@pdf.\MessageBreak
|
|
138
|
+
Check that Node and the triton-latex CLI are installed and that
|
|
139
|
+
\protect\tritoncli\space points at it (e.g.
|
|
140
|
+
\protect\tritoncli{node /path/to/latex/dist/cli.cjs}).}%
|
|
141
|
+
}%
|
|
142
|
+
\else
|
|
143
|
+
\PackageError{triton}{The inline `triton' environment needs shell-escape}{%
|
|
144
|
+
Recompile with -shell-escape (pdflatex/lualatex) or -Z shell-escape
|
|
145
|
+
(tectonic),\MessageBreak or use the precompiled \protect\triton{<name>}
|
|
146
|
+
workflow (render the diagrams to PDF first).}%
|
|
147
|
+
\fbox{\ttfamily[triton: shell-escape required for inline diagram]}%
|
|
148
|
+
\fi
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
% ── Inline environment + backward-compatible command, sharing the name `triton'
|
|
152
|
+
% LaTeX cannot have a command \triton AND an environment `triton' independently,
|
|
153
|
+
% because \begin{triton} simply calls \triton. We resolve this by dispatching on
|
|
154
|
+
% \@currenvir, which LaTeX sets to the environment name inside \begin{...}:
|
|
155
|
+
% • inside \begin{triton} … → start verbatim capture (inline author)
|
|
156
|
+
% • bare \triton[opts]{name} → include a precompiled PDF (fallback)
|
|
157
|
+
\def\triton@marker{triton}
|
|
158
|
+
\newcommand{\triton}{%
|
|
159
|
+
\ifx\@currenvir\triton@marker
|
|
160
|
+
\let\triton@dispatch\triton@beginenv
|
|
161
|
+
\else
|
|
162
|
+
\let\triton@dispatch\triton@include
|
|
163
|
+
\fi
|
|
164
|
+
\triton@dispatch
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
% Environment begin: capture the body verbatim to the temp file. NOTHING may be
|
|
168
|
+
% looked-ahead here (no optional argument), or the line break fancyvrb needs to
|
|
169
|
+
% find the end of the \begin{triton} line is consumed and the first body line is
|
|
170
|
+
% swallowed. \VerbatimEnvironment makes fancyvrb scan until \end{triton}.
|
|
171
|
+
\def\triton@beginenv{%
|
|
172
|
+
\iftriton@nextset
|
|
173
|
+
\let\triton@curopts\triton@nextopts
|
|
174
|
+
\else
|
|
175
|
+
\let\triton@curopts\triton@opts
|
|
176
|
+
\fi
|
|
177
|
+
\VerbatimEnvironment
|
|
178
|
+
\begin{VerbatimOut}{\triton@tmpfile}%
|
|
179
|
+
}
|
|
180
|
+
\def\endtriton{%
|
|
181
|
+
\end{VerbatimOut}%
|
|
182
|
+
\triton@render
|
|
183
|
+
\triton@nextsetfalse
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
% ── \tritoninline[opts]|one-line source| ────────────────────────────────────
|
|
187
|
+
% Convenience for short, single-line diagrams. The body is read verbatim (xparse
|
|
188
|
+
% `v' argument), written to the temp file, and rendered like the environment.
|
|
189
|
+
% Multi-statement diagrams should use the \begin{triton} environment instead.
|
|
190
|
+
\NewDocumentCommand{\tritoninline}{O{\triton@opts} v}{%
|
|
191
|
+
\def\triton@curopts{#1}%
|
|
192
|
+
\immediate\openout\triton@inlinestream=\triton@tmpfile\relax
|
|
193
|
+
\immediate\write\triton@inlinestream{#2}%
|
|
194
|
+
\immediate\closeout\triton@inlinestream
|
|
195
|
+
\triton@render
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
\endinput
|