Marey.Tools.Tex
0.7.0
dotnet add package Marey.Tools.Tex --version 0.7.0
NuGet\Install-Package Marey.Tools.Tex -Version 0.7.0
<PackageReference Include="Marey.Tools.Tex" Version="0.7.0" />
<PackageVersion Include="Marey.Tools.Tex" Version="0.7.0" />
<PackageReference Include="Marey.Tools.Tex" />
paket add Marey.Tools.Tex --version 0.7.0
#r "nuget: Marey.Tools.Tex, 0.7.0"
#:package Marey.Tools.Tex@0.7.0
#addin nuget:?package=Marey.Tools.Tex&version=0.7.0
#tool nuget:?package=Marey.Tools.Tex&version=0.7.0
Marey.Tools.Tex
Mathematical typesetting for Marey, a dimensionally-typed visualization system for F#. TeX sets the formula; the result is geometry, so every backend draws it.
#r "nuget: Marey.Tools.Tex"
open Marey
// A scene whose runs carry TeX — which the axis compiler already fills for you when the
// unit style is `Siunitx`.
let scene = figure |> Chart.toScene extent
let drawn, note = Typeset.sceneOrPlain TexOptions.Default extent scene
printfn "%s" note // says what typeset, and what did not
let png = SkiaBackend.renderPng extent drawn // Skia has never heard of TeX
TextRun.Tex has carried TeX source since M1 and nothing could set it. This runs latex and
dvisvgm over each such run and replaces it with the filled outlines TeX produced — so the
SVG backend, the TikZ backend and the Skia backend all render \frac{\partial \vec{E}}{\partial t}
with the code they already had, and no backend needs a typesetting story of its own.
Both tools are looked for and reported
latex writes DVI; dvisvgm turns DVI into paths. Each is resolved on PATH separately, because
a container image can carry one without the other and "which one is missing" is the useful half of
the message.
printfn "%s" (Typeset.report ())
// latex found at /usr/bin/latex
// dvisvgm found at /usr/bin/dvisvgm — dvisvgm 3.6.1
A missing toolchain is not a failure. TextRun.Text is always set — a run's plain-Unicode
form is never optional — so a figure on a machine with no TeX renders exactly as it would have
without this package, and TypesetUnavailable carries the sentence naming what to install. So
does a single snippet TeX rejects: that run stays as text, is reported by name with TeX's own
complaint, and every other formula on the figure still typesets.
What it costs
About 105 ms of latex and dvisvgm per distinct snippet, memoised on the source within one
call. An ordinary figure carries two — the axis titles — so it is a fifth of a second on an export
path you opt into. The memo does not outlive the call unless you hold one: pass a TexCache to
Typeset.sceneCached for every frame of a film, and only the first frame runs the engine. Five
frames with two formulas cost 1082 ms uncached and 217 ms cached, nearly all of it the first frame.
The cache is keyed on the source, the preamble, the class options, the base size and the tools,
so two callers with different preambles never share an outline. It is safe across the threads a
film renders on.
The size is applied as a scale, not as a second engine run, so one formula at 9 pt and 18 pt
costs one invocation. That is not what a TeX engine would do at 18 pt — real optical sizing picks
a different design — and it is the same trade matplotlib's usetex makes.
Installing the toolchain
- Debian/Ubuntu —
apt install texlive-latex-base texlive-latex-recommended texlive-science dvisvgm - macOS —
brew install --cask mactex(or BasicTeX plustlmgr install dvisvgm) - Windows — MiKTeX, which ships
dvisvgm
dvisvgm is its own package on Debian and Ubuntu and is not pulled in by any texlive-* entry.
Why a subprocess, and why not MathJax
§10 of the design document calls shelling out to TeX "acceptable as a plugin, unacceptable as a
dependency", and that is the whole design brief: this package exists so that nothing in
Marey.Core, Marey.Plot or any backend acquires a TeX installation as a requirement. It takes
no third-party PackageReference of any kind.
The alternative on the table was MathJax through a JavaScript engine, which the roadmap put on the web backend — a backend that does not exist yet, and which would have left the other three unable to set a fraction. Outlines reach all of them.
MIT licensed. Pre-1.0: the API is still free to move.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- FSharp.Core (>= 8.0.100)
- Marey.Core (>= 0.7.0)
- Marey.Toolchain (>= 0.7.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.