| Title: | Native 'LaTeX' Math Rendering for Grid Graphics |
| Version: | 0.0.1 |
| 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. |
| License: | MIT + file LICENSE |
| Encoding: | UTF-8 |
| RoxygenNote: | 7.3.3 |
| SystemRequirements: | C++17, FreeType (>= 2.9), pkg-config |
| Depends: | R (≥ 4.2.0) |
| LinkingTo: | Rcpp, systemfonts |
| Imports: | grDevices, grid, Rcpp, systemfonts, tools |
| Suggests: | ggplot2 (≥ 4.0.0), knitr, ragg, rmarkdown, S7, testthat (≥ 3.0.0), vdiffr |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| URL: | https://github.com/adayim/gridmicrotex, https://adayim.github.io/gridmicrotex/ |
| BugReports: | https://github.com/adayim/gridmicrotex/issues |
| NeedsCompilation: | yes |
| Packaged: | 2026-05-05 13:49:14 UTC; alim |
| Author: | Alim Dayim |
| Maintainer: | Alim Dayim <ad938@cam.ac.uk> |
| Repository: | CRAN |
| Date/Publication: | 2026-05-08 15:00:02 UTC |
gridmicrotex: 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.
Author(s)
Maintainer: Alim Dayim ad938@cam.ac.uk (ORCID)
Other contributors:
Nano Michael (Author of included 'MicroTeX' library) [copyright holder]
Bundled math font authors (See inst/COPYRIGHTS for the full list of authors of the bundled math fonts.) [copyright holder]
See Also
Useful links:
Report bugs at https://github.com/adayim/gridmicrotex/issues
Build a single batched glyphGrob from collected glyph data
Description
Creates a grid::glyphGrob containing all math glyphs,
using grDevices::glyphInfo() to describe glyph IDs, positions,
sizes, colors, and fonts. Each unique font file becomes an entry
in the glyphFontList.
Usage
.build_glyph_grob(ids, x, y, sizes, cols, font_files, depth = 0)
Arguments
ids |
Integer vector of glyph IDs. |
x, y |
Numeric vectors of glyph positions (already y-flipped, in bigpts). |
sizes |
Numeric vector of font sizes. |
cols |
Character vector of colors. |
font_files |
Character vector of font file paths. |
depth |
Depth below the baseline in bigpts (default 0). |
Value
A grid::glyphGrob or NULL.
Get or create a glyphFont object for a font file
Description
Caches grDevices::glyphFont() objects keyed by file path
so that repeated calls for the same font file reuse the same object.
Usage
.get_glyph_font(font_file)
Arguments
font_file |
Absolute path to the OTF/TTF font file. |
Value
A glyphFont object.
Create a text measurement closure for MicroTeX layout
Description
Returns a function that measures text using R's grid graphics system.
The closure is called from C++ during parse_latex_cpp() to get
accurate font metrics for \text{} blocks.
Usage
.make_text_measurer(text_gp)
Arguments
text_gp |
A |
Value
A function taking (text, font_style) that returns
c(width_ratio, ascent_ratio, height_ratio) where ratios
are relative to the font size.
Resolve MicroTeX FontStyle bitmask to R font face
Description
MicroTeX FontStyle: rm=1, bf=2, it=4, etc. (bitmask).
Usage
.resolve_text_face(style)
Arguments
style |
Integer font style bitmask. |
Value
Character: "plain", "bold", "italic",
or "bold.italic".
List available math fonts
Description
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.
Usage
available_math_fonts()
Value
A character vector of math font names.
Font pairing
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.
Examples
available_math_fonts()
Convert big points to TeX points
Description
Convert big points to TeX points
Usage
bigpt_to_tex_pt(big_pt)
Arguments
big_pt |
Numeric value in PostScript points. |
Value
Numeric value in TeX points.
Build grid children from a MicroTeX layout data.frame
Description
Converts each row of the layout data.frame into the appropriate grid grob (pathGrob, segmentsGrob, rectGrob, textGrob, glyphGrob).
Usage
build_latex_children(
layout_df,
total_h,
depth = 0,
text_gp = NULL,
render_mode = "typeface"
)
Arguments
layout_df |
Data.frame returned by |
total_h |
Total height of the formula (height + depth) in bigpts. |
depth |
Depth below the baseline in bigpts (default 0). |
text_gp |
Optional |
render_mode |
Character string: |
Value
A grid::gList of child grobs.
Convert path segments to a grid pathGrob
Description
Convert path segments to a grid pathGrob
Usage
build_path_grob(path_data, col, idx, total_h)
Arguments
path_data |
List with |
col |
Fill color. |
idx |
Index for naming. |
total_h |
Total height for y-axis flipping. |
Value
A grid::pathGrob or NULL.
Check font status
Description
Reports which math fonts are loaded and available for rendering. Shows the MicroTeX version, loaded math fonts, and whether bundled font files are present.
Usage
check_fonts()
Value
Invisibly returns the character vector of available font names.
Examples
check_fonts()
Approximate a cubic bezier curve with line segments
Description
Approximate a cubic bezier curve with line segments
Usage
cubic_bezier(x0, y0, x1, y1, x2, y2, x3, y3, n = 16)
Define a user-level LaTeX macro
Description
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.
Usage
define_macro(name, definition)
clear_macros(name = NULL)
list_macros()
Arguments
name |
Macro name without the leading backslash. For
|
definition |
LaTeX source the macro expands to. |
Value
-
define_macro: Invisibly returnsNULL. -
clear_macros: Invisibly returnsNULL. -
list_macros: A named character vector mapping macro names to their expansions. Empty if no macros are defined.
See Also
Examples
define_macro("RR", "\\mathbb{R}")
define_macro("eps", "\\varepsilon")
grid::grid.newpage()
grid.latex("\\forall \\eps > 0, \\eps \\in \\RR")
clear_macros()
A ggplot2 theme element for LaTeX text
Description
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.
Usage
element_latex(
math_font = "",
fontsize = NULL,
lineheight = 1.2,
max_width = 0,
input_mode = c("math", "mixed"),
render_mode = c("typeface", "path"),
...
)
Arguments
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 |
Details
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.
Value
An S7 object of class element_latex, inheriting from
ggplot2::element_text.
Examples
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())
}
A ggplot2 geom for LaTeX math labels
Description
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.
Usage
geom_latex(
mapping = NULL,
data = NULL,
stat = "identity",
position = "identity",
...,
fontsize = 11,
math_font = "",
lineheight = 1.2,
max_width = 0,
input_mode = c("math", "mixed"),
render_mode = c("typeface", "path"),
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE
)
Arguments
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 |
Value
A ggplot2 layer.
Aesthetics
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)
Examples
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 = "\\hat{y} = \\beta_0 + \\beta_1 x")
}
Set the maximum number of entries kept in the LaTeX layout cache
Description
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.
Usage
latex_cache_limit(n = 512L)
latex_cache_clear()
latex_cache_info()
Arguments
n |
Non-negative integer cache capacity. Default is 512. Set
to |
Value
-
latex_cache_limit: Invisibly returns the previous limit. -
latex_cache_clear: Invisibly returnsNULL. -
latex_cache_info: A list with elementssize(entries currently stored),max_size,hits, andmisses.
See Also
Examples
latex_cache_limit(256)
grid.latex("e^{i\\pi} + 1 = 0")
latex_cache_info()
latex_cache_clear()
Get dimensions of a LaTeX expression
Description
Get dimensions of a LaTeX expression
Usage
latex_dims(
tex,
math_font = "",
max_width = 0,
tex_style = "",
input_mode = c("mixed", "math"),
render_mode = c("typeface", "path"),
gp = grid::gpar()
)
Arguments
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 |
Value
A list with the following elements:
-
width,height,depth: grid unit objects in big points.heightis total height (ascent + descent). -
baseline: grid unit object giving the baseline position measured in big points from the bottom of the bounding box. Equivalent toheight - depthfor single-line formulas. Useful for aligning a formula's baseline with surrounding text. -
is_split: logical;TRUEif the formula was wrapped across multiple lines (only possible whenmax_width > 0).
Examples
latex_dims("\\frac{a}{b}")
Create a grid grob from a LaTeX expression
Description
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.
Usage
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, ...)
Arguments
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 (0-1). |
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 |
Details
Controlling TeX style with 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 intex. 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, orelement_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.
Graphical parameters (gp)
-
col: default foreground color for the formula. Individual elements can still be overridden with an inline\textcolorcommand in the LaTeX string. -
fontfamily/fontface: control the appearance of text inside\textand\mboxblocks. For example,gpar(fontfamily = "serif")renders\textcontent 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 (seemath_font).fontfamilyalso 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 undertools::R_user_dir("gridmicrotex", "cache"), so MicroTeX's spacing of\textblocks stays in sync with what grid actually draws. Whenfontfamilyis 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 isfontsize * cexbig points (default 20 * 1). Both math and text scale together. The effective size is baked into the parsed layout, so downstream viewports that inheritcexwill not re-scale the grob (matchingtextGrobsemantics whengpis set explicitly). -
lineheight: controls multi-line spacing (default 1.2). The inter-line gap is(lineheight - 1) * fontsizebig points.
Value
A grid grob of class "latexgrob".
Invisibly returns the grob.
See Also
grid.latex, latex_dims,
geom_latex, available_math_fonts,
latex_wrap, latex_options
Examples
g <- latex_grob("\\frac{a}{b}", gp = grid::gpar(fontsize = 30))
grid::grid.draw(g)
# Red formula
grid::grid.draw(latex_grob("x^{2}", gp = grid::gpar(col = "red")))
# Rotated formula
grid::grid.draw(latex_grob("x^{2} + y^{2}",
gp = grid::gpar(fontsize = 24), rot = 45))
grid.latex("x^{2} + y^{2} = z^{2}")
Set or query package-wide LaTeX rendering defaults
Description
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.
Usage
latex_options(
math_font = NULL,
render_mode = NULL,
tex_style = NULL,
input_mode = NULL
)
reset_latex_options()
Arguments
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. |
Details
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.
Value
Invisibly returns the previous settings (a list). With no arguments, returns the current settings visibly.
See Also
available_math_fonts, latex_grob
Examples
latex_options(math_font = "stix", render_mode = "typeface")
grid.latex("\\sum_{i=1}^{n} i^{2}", gp = grid::gpar(fontsize = 14))
reset_latex_options()
Inspect the parsed layout of a LaTeX expression
Description
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.
Usage
latex_tree(
tex,
math_font = "",
max_width = 0,
tex_style = "",
input_mode = c("mixed", "math"),
render_mode = c("typeface", "path"),
gp = grid::gpar()
)
Arguments
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 |
Value
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.
See Also
Examples
tree <- latex_tree("\\frac{a}{b}")
print(tree)
head(tree$records)
Wrap standard text for math-first LaTeX renderers
Description
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.
Usage
latex_wrap(tex, input_mode = c("mixed", "math"))
Arguments
tex |
|
input_mode |
|
Details
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.
Value
A character vector of the same length as tex, formatted for
math-mode LaTeX rendering.
Examples
# "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")
Load a math font from an OTF file
Description
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.
Usage
load_font(otf_path)
Arguments
otf_path |
Path to the OTF/TTF font file. |
Details
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.
Value
Invisibly returns NULL.
Text fonts
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.
See Also
available_math_fonts, latex_options,
latex_grob
Examples
# We will download and load Latin Modern Math
url <- "https://mirrors.ctan.org/fonts/lm-math/opentype/latinmodern-math.otf"
math_fnt <- file.path(tempdir(), "latinmodern-math.otf")
download.file(url = url, destfile = math_fnt, mode = "wb")
load_font(math_fnt)
available_math_fonts()
Approximate a quadratic bezier curve with line segments
Description
Approximate a quadratic bezier curve with line segments
Usage
quad_bezier(x0, y0, x1, y1, x2, y2, n = 12)
Resolve a math font name
Description
Translates short aliases (e.g., "stix", "lete") to the
full MicroTeX font name. Validates that the font is loaded.
Usage
resolve_math_font(name)
Arguments
name |
Font name or alias. Empty string uses the default font. |
Value
The resolved font name.
Convert TeX points to big points
Description
TeX points (1/72.27 inch) differ from PostScript/big points (1/72 inch). R's grid "bigpts" unit uses PostScript points.
Usage
tex_pt_to_bigpt(tex_pt)
Arguments
tex_pt |
Numeric value in TeX points. |
Value
Numeric value in big (PostScript) points.