| Title: | Native 'LaTeX' Math Rendering for Grid Graphics |
|---|---|
| Description: | Renders 'LaTeX' math equations as native R grid graphics objects (grobs) using the 'MicroTeX' 'C++' library as the layout engine. Produces resolution-independent vector output that works on any R graphics device, with no external 'LaTeX' installation required. |
| Authors: | Alim Dayim [aut, cre] (ORCID: <https://orcid.org/0000-0001-9998-7463>), Nano Michael [cph] (Author of included 'MicroTeX' library), Bundled math font authors [cph] (See inst/COPYRIGHTS for the full list of authors of the bundled math fonts.) |
| Maintainer: | Alim Dayim <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.0.4 |
| Built: | 2026-05-21 22:23:07 UTC |
| Source: | https://github.com/adayim/gridmicrotex |
Returns the names of all math fonts currently loaded by MicroTeX.
These names can be passed to the math_font parameter of
latex_grob and grid.latex.
available_math_fonts()available_math_fonts()
A character vector of math font names.
The bundled math fonts have different styles. For a consistent look,
pair them with a matching fontfamily in gp:
| Math font | Style | Suggested text font |
Lete Sans Math ("lete", default) |
Sans-serif | "sans" |
STIX Two Math ("stix") |
Serif | "serif"
|
Additional math fonts can be loaded with load_font.
available_math_fonts()available_math_fonts()
Reports which math fonts are loaded and available for rendering. Shows the MicroTeX version, loaded math fonts, and whether bundled font files are present.
check_fonts()check_fonts()
Invisibly returns the character vector of available font names.
check_fonts()check_fonts()
Registers a zero-argument shorthand that is expanded by text
substitution before the expression reaches the MicroTeX parser.
Useful for domain-specific notation (e.g. \RR for
\mathbb{R}) you reuse across many plots.
define_macro(name, definition) clear_macros(name = NULL) list_macros()define_macro(name, definition) clear_macros(name = NULL) list_macros()
name |
Macro name without the leading backslash. For
|
definition |
LaTeX source the macro expands to. |
define_macro: Invisibly returns NULL.
clear_macros: Invisibly returns NULL.
list_macros: A named character vector mapping
macro names to their expansions. Empty if no macros are defined.
define_macro("RR", "\\mathbb{R}") define_macro("eps", "\\varepsilon") grid::grid.newpage() grid.latex("\\forall \\eps > 0, \\eps \\in \\RR") clear_macros()define_macro("RR", "\\mathbb{R}") define_macro("eps", "\\varepsilon") grid::grid.newpage() grid.latex("\\forall \\eps > 0, \\eps \\in \\RR") clear_macros()
Use this as a theme element for axis titles, axis labels, plot titles, or any other text element in a ggplot2 theme. The text string is parsed as LaTeX math and rendered via MicroTeX.
element_latex( math_font = "", fontsize = NULL, lineheight = 1.2, max_width = 0, input_mode = c("mixed", "math"), render_mode = c("typeface", "path"), ... )element_latex( math_font = "", fontsize = NULL, lineheight = 1.2, max_width = 0, input_mode = c("mixed", "math"), render_mode = c("typeface", "path"), ... )
math_font |
Name of the math font to use (e.g., |
fontsize |
Convenience alias for |
lineheight |
Multi-line height multiplier (default 1.2), matching
|
max_width |
Numeric maximum width in big points for automatic
line wrapping. Use |
input_mode |
How |
render_mode |
Character string: |
... |
Additional arguments passed to |
Dollar signs ($...$) in the label text are stripped automatically
so that both "\frac{a}{b}" and "$\frac{a}{b}$" work.
This element is an S7 subclass of ggplot2::element_text, so it
inherits all standard text properties (size, colour, hjust, etc.) from
the theme and supports merge_element() correctly.
An S7 object of class element_latex, inheriting from
ggplot2::element_text.
if (requireNamespace("ggplot2", quietly = TRUE)) { library(ggplot2) ggplot(mtcars, aes(wt, mpg)) + geom_point() + labs(x = "$\\beta_1 \\cdot x + \\beta_0$") + theme(axis.title.x = element_latex()) }if (requireNamespace("ggplot2", quietly = TRUE)) { library(ggplot2) ggplot(mtcars, aes(wt, mpg)) + geom_point() + labs(x = "$\\beta_1 \\cdot x + \\beta_0$") + theme(axis.title.x = element_latex()) }
Renders LaTeX math expressions as native grid grobs within a ggplot2 plot. Each label is parsed and laid out by MicroTeX, producing resolution-independent vector output.
geom_latex( mapping = NULL, data = NULL, stat = "identity", position = "identity", ..., fontsize = 11, math_font = "", lineheight = 1.2, max_width = 0, input_mode = c("mixed", "math"), render_mode = c("typeface", "path"), na.rm = FALSE, show.legend = NA, inherit.aes = TRUE )geom_latex( mapping = NULL, data = NULL, stat = "identity", position = "identity", ..., fontsize = 11, math_font = "", lineheight = 1.2, max_width = 0, input_mode = c("mixed", "math"), render_mode = c("typeface", "path"), na.rm = FALSE, show.legend = NA, inherit.aes = TRUE )
mapping |
Set of aesthetic mappings created by |
data |
The data to be displayed in this layer. There are three options: If A A |
stat |
The statistical transformation to use on the data for this layer.
When using a
|
position |
A position adjustment to use on the data for this layer. This
can be used in various ways, including to prevent overplotting and
improving the display. The
|
... |
Other arguments passed to |
fontsize |
Default font size in points. Overridden by the |
math_font |
Name of the math font to use (e.g., |
lineheight |
Multi-line height multiplier (default 1.2), matching
|
max_width |
Maximum width in big points for automatic line wrapping (default: 0, no wrapping). |
input_mode |
How |
render_mode |
Character string: |
na.rm |
If |
show.legend |
logical. Should this layer be included in the legends?
|
inherit.aes |
If |
A ggplot2 layer.
geom_latex() understands the following aesthetics (required aesthetics
are in bold):
x
y
label — LaTeX math string
size — font size in points (default: 11)
colour — text colour (default: "black")
angle — rotation angle in degrees (default: 0)
hjust — horizontal justification, 0–1 (default: 0.5)
vjust — vertical justification, 0–1 (default: 0.5)
alpha — transparency (default: 1)
if (requireNamespace("ggplot2", quietly = TRUE)) { library(ggplot2) df <- data.frame( x = 1:3, y = 1:3, eq = c("x^2", "\\frac{a}{b}", "\\sum_{i=1}^n x_i") ) ggplot(df, aes(x, y, label = eq)) + geom_latex() # Use annotate() for single annotations (no legend, no data frame needed) ggplot(mtcars, aes(wt, mpg)) + geom_point() + annotate("latex", x = 4, y = 30, label = r"($\hat{y} = \beta_0 + \beta_1 x$)") }if (requireNamespace("ggplot2", quietly = TRUE)) { library(ggplot2) df <- data.frame( x = 1:3, y = 1:3, eq = c("x^2", "\\frac{a}{b}", "\\sum_{i=1}^n x_i") ) ggplot(df, aes(x, y, label = eq)) + geom_latex() # Use annotate() for single annotations (no legend, no data frame needed) ggplot(mtcars, aes(wt, mpg)) + geom_point() + annotate("latex", x = 4, y = 30, label = r"($\hat{y} = \beta_0 + \beta_1 x$)") }
Resolves a \mark{name} that was placed inside the LaTeX
source to a pair of grid units in the grob's parent viewport.
The returned units already account for the grob's viewport position
and hjust/vjust, so you can pass them directly to grid
drawing functions to anchor other graphics on parts of the formula.
grobMark(grob, name)grobMark(grob, name)
grob |
A |
name |
The mark name (the argument to |
A list with elements x and y, each a
unit. Mark coordinates are evaluated in the
grob's parent viewport.
g <- latex_grob(r"($a\mark{eq}^2 = b + c^2$)", x = grid::unit(0.5, "npc"), y = grid::unit(0.5, "npc")) grid::grid.newpage(); grid::grid.draw(g) mk <- grobMark(g, "eq") grid::grid.points(mk$x, mk$y, pch = 19, gp = grid::gpar(col = "red"))g <- latex_grob(r"($a\mark{eq}^2 = b + c^2$)", x = grid::unit(0.5, "npc"), y = grid::unit(0.5, "npc")) grid::grid.newpage(); grid::grid.draw(g) mk <- grobMark(g, "eq") grid::grid.points(mk$x, mk$y, pch = 19, gp = grid::gpar(col = "red"))
The cache stores parsed layout information for recently rendered LaTeX expressions, keyed by the expression and relevant rendering parameters (font, size, macros, etc.). This speeds up repeated rendering of the same expressions, especially in loops or interactive sessions. The default limit is 512 entries, which should be sufficient for most use cases. When the limit is exceeded, the least recently used entries are automatically evicted.
latex_cache_limit(n = 512L) latex_cache_clear() latex_cache_info()latex_cache_limit(n = 512L) latex_cache_clear() latex_cache_info()
n |
Non-negative integer cache capacity. Default is 512. Set
to |
latex_cache_limit: Invisibly returns the previous limit.
latex_cache_clear: Invisibly returns NULL.
latex_cache_info: A list with elements size
(entries currently stored), max_size, hits, and
misses.
latex_cache_limit(256) grid.latex("e^{i\\pi} + 1 = 0") latex_cache_info() latex_cache_clear()latex_cache_limit(256) grid.latex("e^{i\\pi} + 1 = 0") latex_cache_info() latex_cache_clear()
Get dimensions of a LaTeX expression
latex_dims( tex, math_font = "", max_width = 0, tex_style = "", input_mode = c("mixed", "math"), render_mode = c("typeface", "path"), gp = grid::gpar() )latex_dims( tex, math_font = "", max_width = 0, tex_style = "", input_mode = c("mixed", "math"), render_mode = c("typeface", "path"), gp = grid::gpar() )
tex |
Character string of LaTeX math code. |
math_font |
Name of the math font to use (e.g., |
max_width |
Numeric maximum width in big points for automatic
line wrapping. Use |
tex_style |
Character: TeX style override. One of |
input_mode |
How |
render_mode |
Character string: |
gp |
Graphical parameters (see |
A list with the following elements:
width, height, depth: grid unit objects
in big points. height is total height (ascent + descent).
baseline: grid unit object giving the baseline position
measured in big points from the bottom of the bounding box.
Equivalent to height - depth for single-line formulas. Useful
for aligning a formula's baseline with surrounding text.
is_split: logical; TRUE if the formula was wrapped
across multiple lines (only possible when max_width > 0).
latex_dims("\\frac{a}{b}")latex_dims("\\frac{a}{b}")
Parses a LaTeX math expression and returns a grid grob object
that renders the formula using native grid graphics primitives.
The grob supports standard grid queries such as grobWidth(),
grobHeight(), grobX(), and grobY().
A convenience wrapper that creates a latex_grob and
immediately draws it on the current device via
grid.draw.
latex_grob( tex, x = grid::unit(0.5, "npc"), y = grid::unit(0.5, "npc"), default.units = "npc", hjust = 0.5, vjust = 0.5, rot = 0, math_font = "", max_width = 0, tex_style = "", input_mode = c("mixed", "math"), render_mode = c("typeface", "path"), debug = FALSE, name = NULL, gp = grid::gpar() ) grid.latex(tex, ...)latex_grob( tex, x = grid::unit(0.5, "npc"), y = grid::unit(0.5, "npc"), default.units = "npc", hjust = 0.5, vjust = 0.5, rot = 0, math_font = "", max_width = 0, tex_style = "", input_mode = c("mixed", "math"), render_mode = c("typeface", "path"), debug = FALSE, name = NULL, gp = grid::gpar() ) grid.latex(tex, ...)
tex |
Character string of LaTeX math code. |
x, y
|
Position in grid coordinates. |
default.units |
Units for x, y if given as numeric. |
hjust, vjust
|
Horizontal/vertical justification. Accepts the
usual numeric values in |
rot |
Rotation angle in degrees, counter-clockwise (default: 0).
Matches the |
math_font |
Name of the math font to use (e.g., |
max_width |
Numeric maximum width in big points for automatic
line wrapping. Use |
tex_style |
Character: TeX style override. One of |
input_mode |
How |
render_mode |
Character string: |
debug |
Logical; if |
name |
Optional grob name. |
gp |
Graphical parameters (see |
... |
Additional arguments passed to |
tex_style
tex_style selects the size-and-spacing regime MicroTeX applies to
the whole expression. It changes the style (display vs. text), not
the font size — size is always set via gp$fontsize / gp$cex;
style-dependent shrinking (for "script" and "scriptscript") is
applied on top of that size.
"" (default): let the parser choose based on the delimiters in
tex. Inline delimiters (single $, or \(...\)) produce
"text" style; display delimiters (double $$, or \[...\])
produce "display" style. If the string has no delimiters,
MicroTeX defaults to "text" style.
"display": force display style. Large operators (\sum,
\int, \prod) render at their full size, limits are placed
above/below rather than as subscripts/superscripts, and fractions
use full-size numerators and denominators. Useful when you want a
display-style equation inline in a label, legend, or
element_latex() title.
"text": force text (inline) style. Big operators shrink to their
inline size and limits attach as scripts. The right choice for
formulas embedded in a line of prose.
"script": force script style — the size normally used for
first-level subscripts and superscripts. Produces a smaller,
tighter layout; mainly useful for callouts or sub-labels where a
compact equation is wanted.
"scriptscript": force scriptscript style — the smallest style,
used by TeX for doubly-nested scripts. Rarely needed on its own;
primarily for very dense annotations.
tex_style applies to the entire expression. To override the style
of a sub-expression from within tex, use the inline TeX commands
\displaystyle, \textstyle, \scriptstyle, or
\scriptscriptstyle.
gp)col: default foreground color for the formula. Individual
elements can still be overridden with an inline \textcolor
command in the LaTeX string.
fontfamily / fontface: control the appearance of text inside
\text and \mbox blocks. For example, gpar(fontfamily = "serif") renders \text content in R's serif family. Any font
available to R's graphics system works — base families
("sans", "serif", "mono") as well as fonts registered via
showtext or systemfonts. Math symbols always use the
selected math font (see math_font).
fontfamily also drives MicroTeX's layout metrics for non-math
text: the matching system font is resolved via systemfonts,
a minimal metrics file is generated on first use and cached under
tools::R_user_dir("gridmicrotex", "cache"), so MicroTeX's
spacing of \text blocks stays in sync with what grid
actually draws. When fontfamily is unset, the R default
("sans") is used. No manual font loading is required for text
fonts; load_font() remains only for adding custom math
fonts.
fontsize / cex: formula size is fontsize * cex big points
(default 20 * 1). Both math and text scale together. The effective
size is baked into the parsed layout, so downstream viewports that
inherit cex will not re-scale the grob (matching textGrob
semantics when gp is set explicitly).
lineheight: controls multi-line spacing (default 1.2). The
inter-line gap is (lineheight - 1) * fontsize big points.
The parser accepts raw output from print.xtable(),
knitr::kable(), and similar functions that emit complete
tabular LaTeX. The following document-level constructs are
recognized and rewritten silently before the input reaches MicroTeX:
Removed (no visual effect):
%-to-end-of-line comments (escaped \% is preserved)
preamble: \documentclass[...]{...}, \usepackage[...]{...},
\begin{document} / \end{document}
title metadata: \maketitle, \title{...}, \author{...}
cross-reference labels: \label{...}
float wrappers: \begin{table} / \end{table}, \begin{figure} /
\end{figure} (and starred variants)
layout scopes: \centering, \raggedright, \raggedleft,
\flushleft, \flushright
Rewritten:
booktabs rules: \toprule, \midrule, \bottomrule, \cmidrule
are mapped to \hline. The optional column-range and trim
arguments of \cmidrule are discarded (MicroTeX has no concept of
partial-column rules).
\caption[short]{X} is extracted as \text{X}\\ at its source
position. The caption renders where it appears in the input
(typically below the tabular for xtable, above for
kable); expect a slight visual difference from full LaTeX,
which positions the caption above or below the float regardless of
source order.
Anything not in this list is passed to MicroTeX unchanged. Unknown commands render as literal text, which is useful for spotting unsupported markup.
The MicroTeX engine keeps mutable C++ state for font caching and text
measurement. Rendering is safe single-threaded and under separate-process
backends such as future::plan(multisession). It is not safe
under forked backends (parallel::mclapply(),
future::plan(multicore)) on Unix, because forked workers share that
state without synchronisation. Use a socket/multisession backend instead.
A grid grob of class "latexgrob".
Invisibly returns the grob.
grid.latex, latex_dims,
geom_latex, available_math_fonts,
latex_wrap, latex_options
g <- latex_grob(r"($\fcolorbox{red}{yellow}{\frac{a}{b}}$)", x = grid::unit(0.3, "npc"), y = grid::unit(0.3, "npc"), gp = grid::gpar(fontsize = 30)) grid::grid.draw(g) # Red formula grid::grid.draw(latex_grob("$x^{2}$", x = grid::unit(0.3, "npc"), y = grid::unit(0.8, "npc"), gp = grid::gpar(col = "red"))) # Rotated formula grid::grid.draw(latex_grob(r"($\colorbox{BurntOrange}{x^{2}} + y^{2}$)", x = grid::unit(0.6, "npc"), y = grid::unit(0.3, "npc"), gp = grid::gpar(fontsize = 24), rot = 45)) grid.latex(r"($\textcolor{red}{x^{2}} + y^{2} = z^{2}$)", x = grid::unit(0.6, "npc"), y = grid::unit(0.8, "npc"),)g <- latex_grob(r"($\fcolorbox{red}{yellow}{\frac{a}{b}}$)", x = grid::unit(0.3, "npc"), y = grid::unit(0.3, "npc"), gp = grid::gpar(fontsize = 30)) grid::grid.draw(g) # Red formula grid::grid.draw(latex_grob("$x^{2}$", x = grid::unit(0.3, "npc"), y = grid::unit(0.8, "npc"), gp = grid::gpar(col = "red"))) # Rotated formula grid::grid.draw(latex_grob(r"($\colorbox{BurntOrange}{x^{2}} + y^{2}$)", x = grid::unit(0.6, "npc"), y = grid::unit(0.3, "npc"), gp = grid::gpar(fontsize = 24), rot = 45)) grid.latex(r"($\textcolor{red}{x^{2}} + y^{2} = z^{2}$)", x = grid::unit(0.6, "npc"), y = grid::unit(0.8, "npc"),)
A single entry point for project-wide defaults used by
latex_grob, grid.latex,
latex_dims, and latex_tree. Options set
here are applied only when the corresponding argument is not
supplied at the call site, so explicit arguments always win.
latex_options( math_font = NULL, render_mode = NULL, tex_style = NULL, input_mode = NULL ) reset_latex_options()latex_options( math_font = NULL, render_mode = NULL, tex_style = NULL, input_mode = NULL ) reset_latex_options()
math_font |
Math font name or alias (see
|
render_mode |
Either |
tex_style |
TeX style override. One of |
input_mode |
How the input string is interpreted before being
handed to MicroTeX. |
Calling latex_options() with no arguments returns the current
settings (a list whose NULL entries mean "use the built-in
default"). Supply one or more named arguments to update them.
Font size and line spacing are controlled via gp parameters
(fontsize, cex, lineheight) at the grob level
— see latex_grob.
Invisibly returns the previous settings (a list). With no arguments, returns the current settings visibly.
available_math_fonts, latex_grob
latex_options(math_font = "stix", render_mode = "typeface") grid.latex("\\sum_{i=1}^{n} i^{2}", gp = grid::gpar(fontsize = 14)) reset_latex_options()latex_options(math_font = "stix", render_mode = "typeface") grid.latex("\\sum_{i=1}^{n} i^{2}", gp = grid::gpar(fontsize = 14)) reset_latex_options()
Returns the raw draw-record table produced by MicroTeX's layout pass together with the bounding-box metadata. Useful for debugging alignment issues, building custom grobs on top of the layout, or counting glyphs/paths/rules in a formula.
latex_tree( tex, math_font = "", max_width = 0, tex_style = "", input_mode = c("mixed", "math"), render_mode = c("typeface", "path"), gp = grid::gpar() )latex_tree( tex, math_font = "", max_width = 0, tex_style = "", input_mode = c("mixed", "math"), render_mode = c("typeface", "path"), gp = grid::gpar() )
tex |
Character string of LaTeX math code. |
math_font |
Name of the math font to use (e.g., |
max_width |
Numeric maximum width in big points for automatic
line wrapping. Use |
tex_style |
Character: TeX style override. One of |
input_mode |
How |
render_mode |
Character string: |
gp |
Graphical parameters (see |
A list with class "latex_tree" containing:
recordsData frame of draw records (one row per
glyph, path, line, rect, or text block). Columns include
type, x, y, glyph, font_size,
color, text, codepoint, font_file.
bboxNamed numeric vector with width,
height, depth, baseline (all in big points).
texThe (macro-expanded) input string.
render_modeRendering mode used for the layout.
tree <- latex_tree("\\frac{a}{b}") print(tree) head(tree$records)tree <- latex_tree("\\frac{a}{b}") print(tree) head(tree$records)
Parses character strings to safely isolate standard natural language from
LaTeX math environments. Standard text is wrapped in \text{} blocks, while
equations, display math, and specific LaTeX environments are preserved verbatim.
This is heavily optimized for passing mixed-content strings (like plot titles
or axis labels) to pure-math typesetting engines like MicroTex. The conversion
is not perfect, but it should handle most common cases without user intervention.
latex_wrap(tex, input_mode = c("mixed", "math"))latex_wrap(tex, input_mode = c("mixed", "math"))
tex |
|
input_mode |
|
latex_wrap() operates as a state-machine tokenizer to ensure that valid LaTeX
math is not corrupted by the text-wrapping process. It features:
Delimiter Preservation: Standard inline ($, \() and block ($$, \[)
math delimiters are recognized and preserved.
Environment Tracking: Complex nested environments (e.g., \begin{matrix})
are safely extracted and bypassed.
Newline Conversion: R newline characters (\n) occurring outside of math
environments are automatically converted to LaTeX line breaks (\\) inside
the \text{} wrapper.
Literal Escapes: Escaped LaTeX literals (e.g., \$, \%, \#) are
safely passed into the \text{} block without triggering math modes. The
escape character for \$ is automatically resolved for MicroTex compatibility.
A character vector of the same length as tex, formatted for
math-mode LaTeX rendering.
# "mixed" mode (default) safely wraps text and preserves inline math latex_wrap(r"(The equation \(E=mc^2\) is famous)") # "mixed" mode handles user-escaped characters seamlessly latex_wrap(r"(Cost: \$100 for $x$ items)") # "mixed" mode converts R newlines to stacked text blocks latex_wrap(r"(Line 1\nLine 2)") # "math" mode returns the string completely unmodified latex_wrap(r"(\frac{\alpha}{\beta})", input_mode = "math")# "mixed" mode (default) safely wraps text and preserves inline math latex_wrap(r"(The equation \(E=mc^2\) is famous)") # "mixed" mode handles user-escaped characters seamlessly latex_wrap(r"(Cost: \$100 for $x$ items)") # "mixed" mode converts R newlines to stacked text blocks latex_wrap(r"(Line 1\nLine 2)") # "math" mode returns the string completely unmodified latex_wrap(r"(\frac{\alpha}{\beta})", input_mode = "math")
Loads an OTF/TTF math font into MicroTeX's internal font registry. The
font's OpenType MATH table is parsed directly in C++ and the required
metrics are synthesised on the fly. You can download free math fonts like
Latin Modern Math (default math fonts in LaTeX) and load it with
load_font() to use it for math rendering.
load_font(otf_path)load_font(otf_path)
otf_path |
Path to the OTF/TTF font file. |
The font is also registered with the systemfonts package so it
can be selected for surrounding plot text via
gp = gpar(fontfamily = "...") without being installed
system-wide.
Invisibly returns NULL.
This function is only for math fonts (fonts with an
OpenType MATH table). Plain text fonts used inside \text{}
blocks are resolved automatically by systemfonts from the
gp$fontfamily argument — no load_font() call required.
available_math_fonts, latex_options,
latex_grob
# Load a math font from a local OTF file. Here we point at the # bundled STIX font so the example is self-contained and loaded. # You don't need to load the bundled fonts to use them — they're registered # with systemfonts on first render — but this shows how to load a custom font. # in practice you would pass the path to any OTF with an OpenType MATH table. otf <- system.file("fonts", "STIXTwoMath-Regular.otf", package = "gridmicrotex") load_font(otf) available_math_fonts()# Load a math font from a local OTF file. Here we point at the # bundled STIX font so the example is self-contained and loaded. # You don't need to load the bundled fonts to use them — they're registered # with systemfonts on first render — but this shows how to load a custom font. # in practice you would pass the path to any OTF with an OpenType MATH table. otf <- system.file("fonts", "STIXTwoMath-Regular.otf", package = "gridmicrotex") load_font(otf) available_math_fonts()