---
title: "Get Started"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Get Started}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 7,
  fig.height = 4.6,
  fig.align = "center"
)
```

```{r libraries, message = FALSE, include = FALSE}
library(ggplot2)
library(ggtypst)
```

## Why `ggtypst`?

ℹ️ One sentence summary: **`ggtypst` is for the moments when plain plot text is not expressive enough, but a full external LaTeX workflow would be too heavy.**

---

Consider these scenarios: you have a scientific plot, and now you want to:

- show your title with multiple styles, for example, the first word is red and the rest is blue
- add some special characters like Greek letters in your axis titles
- add high-quality complex math expressions as annotations in the plot
- use the corresponding regression equation as the title of each facet

How would you achieve this?

- Base `ggplot2` text helpers are great for ordinary labels, but scientific and
technical plots often need more than plain strings.
- You can use `expression()` in base R to add math. But its syntax is not natural and its functionality is limited.
- The package [`latex2exp`](https://www.stefanom.io/latex2exp/) helps you convert LaTeX math expressions to R expressions. But its functionality is also limited by `expression()`.
- The package [`ggtext`](https://github.com/wilkelab/ggtext) allows you to use Markdown and HTML tags to style your text. But it doesn't support complex styles and math.
- [`tikzDevice`](https://github.com/daqana/tikzDevice)/[`ggtikz`](https://github.com/osthomas/ggtikz) allows you to use LaTeX. But it is too complex to use and must rely on external TeX toolchains, which are very heavy.
- ...

So is there a simple, lightweight, easy-to-use solution? Yes, that's why `ggtypst` is here!

---

[Typst](https://typst.app) is a modern markup language and typesetting engine written
in Rust. You can write source text such as `*bold*`, `_italic_`, `#linebreak()`,
or `$ sum_(i=1)^n x_i $`, and Typst turns it into polished rendered output.
It is fast, simple but powerful, solving these pain points perfectly and elegantly.

`ggtypst` uses Typst's Rust engine as the rendering backend and offers a series of
functions to fit `ggplot2` workflow. With `ggtypst`, you don't need to leave your
`ggplot2` workflow, don't need to rely on external LaTeX or Typst, and can easily solve
all the above use cases.

<details>
<summary>Click to see the code</summary>

```{r why-ggtypst, eval = FALSE}
eq_labels <- by(mtcars, mtcars$cyl, function(df) {
  fit <- lm(mpg ~ wt, data = df)
  coef <- unname(coef(fit))

  sprintf(
    "hat(y) = %.1f %s %.1f x",
    coef[1],
    if (coef[2] < 0) "-" else "+",
    abs(coef[2])
  )
})

ggplot(mtcars, aes(wt, mpg)) +
  geom_point(color = "grey50", size = 2) +
  geom_smooth(method = "lm", formula = y ~ x, se = FALSE, linewidth = 0.7, color = "#1D4E89") +
  facet_wrap(vars(cyl), nrow = 1, labeller = as_labeller(eq_labels)) +
  annotate_math_typst(
    r"(R^2 = 1 - sum(y_i - hat(y)_i)^2 / sum(y_i - macron(y))^2)",
    x = 3.5,
    y = 33.5,
    size = 10
  ) +
  labs(
    title = r"(#text(fill: red)[Scientific] #text(fill: blue)[plot text, math, and facet equations])",
    x = "Weight α (1000 lbs)",
    y = "Fuel economy η (mpg)",
    caption = "Smooth line formula: $y ~ x$"
  ) +
  theme(
    plot.title = element_typst(size = 16, face = "bold"),
    axis.title.x = element_typst(size = 12, colour = "#102A43"),
    axis.title.y = element_typst(size = 12, colour = "#102A43"),
    strip.text = element_math_typst(size = 12, face = "bold"),
    plot.caption = element_typst(size = 9, color = "grey50", face = "italic")
  )
```

</details>

```{r why-ggtypst-eval, echo = FALSE}
eq_labels <- by(mtcars, mtcars$cyl, function(df) {
  fit <- lm(mpg ~ wt, data = df)
  coef <- unname(coef(fit))

  sprintf(
    "hat(y) = %.1f %s %.1f x",
    coef[1],
    if (coef[2] < 0) "-" else "+",
    abs(coef[2])
  )
})

ggplot(mtcars, aes(wt, mpg)) +
  geom_point(color = "grey50", size = 2) +
  geom_smooth(method = "lm", formula = y ~ x, se = FALSE, linewidth = 0.7, color = "#1D4E89") +
  facet_wrap(vars(cyl), nrow = 1, labeller = as_labeller(eq_labels)) +
  annotate_math_typst(
    r"(R^2 = 1 - sum(y_i - hat(y)_i)^2 / sum(y_i - macron(y))^2)",
    x = 3.5,
    y = 33.5,
    size = 10
  ) +
  labs(
    title = r"(#text(fill: red)[Scientific] #text(fill: blue)[plot text, math, and facet equations])",
    x = "Weight α (1000 lbs)",
    y = "Fuel economy η (mpg)",
    caption = "Smooth line formula: $y ~ x$"
  ) +
  theme(
    plot.title = element_typst(size = 16, face = "bold"),
    axis.title.x = element_typst(size = 12, colour = "#102A43"),
    axis.title.y = element_typst(size = 12, colour = "#102A43"),
    strip.text = element_math_typst(size = 12, face = "bold"),
    plot.caption = element_typst(size = 9, color = "grey50", face = "italic")
  )
```

## Installation

Install `ggtypst` from R-universe first so you can use the prebuilt package and
avoid compiling Rust locally:

```{r install, eval = FALSE}
install.packages("ggtypst", repos = "https://yousa-mirage.r-universe.dev")
```

If you need the latest development version from GitHub, you can install it
from source:

```{r install-github, eval = FALSE}
install.packages("remotes")
remotes::install_github("Yousa-Mirage/ggtypst")
```

Because the GitHub installation builds the Typst backend in Rust, you need
`rustc` and `cargo` on your system to compile it. Particularly on Windows, you
must use the `x86_64-pc-windows-gnu` toolchain. Regardless of how you install
`ggtypst`, you don't need a separate local Typst or LaTeX installation to use
it.

## First plot

A quick example is like this:

```{r first-plot}
ggplot(mtcars, aes(wt, mpg)) +
  geom_point(color = "grey50") +
  annotate_typst(
    typst_code = "*Hello from Typst!* #linebreak() $sum_(i=1)^n x_i$",
    x = 4.8,
    y = 32,
    size = 14,
    color = "#1D4E89"
  ) +
  labs(
    title = "A first ggtypst plot",
    x = "Weight (1000 lbs)",
    y = "integral_0^1 x^2 dif x = 1/3"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_typst(size = 16, face = "bold.italic", colour = "#102A43"),
    axis.title.y = element_math_typst(size = 14, colour = "#1D4E89")
  )
```

This shows the core usage of the package:

1. First, we use `annotate_typst()` to add a Typst label containing text and inline math.
    - `* ... *` marks bold text.
    - `#linebreak()` inserts a line break.
    - `$...$` marks inline math.
    - We specified the plot location, text size and color by other arguments.
2. Then, we want to render the title and axis titles with Typst.
    - We write a common title, and then render it with Typst through `element_typst()`.
    - We want to use a math expression as the y-axis title, so we write the Typst math source code in `labs()` and then use `element_math_typst()` to render it.

## When to use annotate, geom, and element

Use the three function families according to where the rendered content comes
from.

| Function family | Best for | Typical use |
|---|---|---|
| `annotate_*()` | one manually placed label | a callout, note, or equation |
| `geom_*()` | one label per row of data | point labels, grouped labels, math annotations |
| `element_*()` | theme text | titles, subtitles, axis text, strips, legends |

## R raw strings

Typst and LaTeX source strings may contain lots of `"` and `\`. In ordinary R strings, these characters need to be escaped like `"\\frac{a}{b}"`. Introduced in R 4.0.0, R raw strings let you write these special characters directly without escaping.

ℹ️ ***You should ALWAYS use the raw string `r"( ... )"` in your Typst and LaTeX source:***

```{r raw-strings, eval = FALSE}
r"(*bold text*)"
r"($"a text in math" sum_(i=1)^n x_i$)"
r"(\frac{a}{b})"
```

## Text, Typst math, and MiTeX math

`ggtypst` supports three related but different kinds of content.

### Typst markup content

Typst is a language for typesetting documents. It has two modes: the markup mode and the function mode. In markup mode, you write plain text with Typst markup syntax, similar to writing Markdown. For more details, please see the [Typst documentation](https://typst.app/docs/). It's very easy to learn and use.

Use `annotate_typst()`, `geom_typst()`, or `element_typst()` when the label is
mostly text. For example:

```r
annotate_typst(
  typst_code = r"(*bold text*)",  # `*...*` means bold text
  x = 1,
  y = 1
) +
annotate_typst(
  typst_code = r"($a^2 + b^2 = c^2$)",  # `$...$` means inline math
  x = 2,
  y = 2
) +
annotate_typst(
  # In the line below, "Red text" is styled with `fill: red`, "default text" is styled with italic, and `+` is with default style.
  typst_code = r"(#text(fill: "red")[Red text] + _default text_)",
  x = 3,
  y = 3
)
```

Yeah, actually you can write any legal Typst content in `typst_code`, including math, styled text, layouts, and functions. You can even write a full Typst document in `typst_code`, as long as the source string is legal Typst content. They will be directly rendered by Typst.

### Native Typst math

You can use `*_math_typst()` when you want to write math directly. They are wrappers
around `*_typst()` that use the `typst_math_code` argument instead of `typst_code`.

```{r typst-math-example, eval = FALSE}
annotate_math_typst(
  typst_math_code = r"(sum_(i=1)^n x_i)",
  x = 1,
  y = 1
)
```

`$ ... $` or `$...$` will be automatically added around your math code to make sure it
is rendered as a math expression. The difference is, `$ ... $`, which is default, means
display math, while `$...$` means inline math. You can use the `inline` argument to
control which to use.

Of course, you can also use `annotate_typst()` and write your math code in `$ ... $` or
`$...$`. `*_math_typst()` are just more convenient wrappers.

One more important benefit of Typst is that you don't need to have a math font
installed on your system to render math expressions. Typst has embedded the
`New Computer Modern Math` font in binary, so you can render math anywhere and anytime.

### MiTeX-backed LaTeX math

You can use `annotate_math_mitex()`, `geom_math_mitex()`, or `element_math_mitex()` if
you are more familiar with LaTeX math syntax or when your input is already in LaTeX.
`ggtypst` converts LaTeX math into Typst math by [MiTeX](https://github.com/mitex-rs/mitex)
in the Rust backend. According to their documentation, this conversion is stable and
supports a wide range of LaTeX math syntax.

```{r mitex-example, eval = FALSE}
annotate_math_mitex(
  latex_math_code = r"(\frac{1}{2} + \sqrt{3})",
  x = 1,
  y = 1
)
```

## `annotate_*()`: one-off plot annotations

`annotate_*()` is the easiest place to start because it behaves like a normal
manual annotation layer. Use this function family when you just want to add one
rich text note or math equation at a specific position.

```{r annotate-example}
ggplot(mtcars, aes(wt, mpg)) +
  geom_point(color = "grey65") +
  annotate_typst(
    typst_code = r"(Some plain text)",
    x = 2,  # You must specify the x and y position manually
    y = 15
  ) +
  annotate_typst(
    typst_code = paste(
      r"(*Fuel economy* #linebreak())",  # text with bold markup and line break function
      r"(#text(fill: rgb("#1D4E89"))[Typst text] +)",  # text with fill color
      r"($integral_0^1 x^2 dif x = 1 / 3$)"  # inline math
    ),
    x = 4,
    y = 33,
    size = 12,
    color = "#102A43"
  ) +
  annotate_math_mitex(
    latex_math_code = r"(\eta = \frac{mpg}{wt})",  # LaTeX math code
    x = 5,
    y = 25,
    size = 14,
    color = "green",
    face = "bold"
  ) +
  theme_minimal(base_size = 12)
```

## `geom_*()`: data-driven labels

`geom_*()` turns Typst source strings into a true data layer. Each row gets its own
rendered label and can map aesthetics like `colour`, `angle`, and
`face`. Use this family when:

- you have many labels to render
- labels come from rows in a data frame
- each label may have different styling
- you want Typst output to behave like other `ggplot2` geoms

```{r geom-example}
labels <- data.frame(
  wt = c(2, 3, 5),
  mpg = c(33, 25, 15),
  label = c(
    r"(*Toyota Corolla* #linebreak() 33.9 mpg)",
    r"(*Fiat 128* #linebreak() nimble + efficient)",
    r"(*Maserati Bora* #linebreak() $v_8$ flagship)"
  ),
  colour = c("yellow", "#3A86A8", "#7A1E48"),
  face = c("italic", "bold.italic", "bold")
)

ggplot(mtcars, aes(wt, mpg)) +
  geom_point(color = "grey80", size = 2) +
  geom_typst(
    data = labels,
    aes(wt, mpg, label = label, colour = colour, face = face),
    size = 12,
    show.legend = FALSE
  ) +
  scale_colour_identity() +  # this is needed for colour mapping
  theme_minimal(base_size = 12)
```

However, be careful not to use geom_typst() to render more than 50 label rows, as it will not only slow down rendering but also make your plot hard to read. For more
details on performance, see [the benchmark result](https://yousa-mirage.github.io/ggtypst/articles/benchmark.html).

## `element_*()`: Typst in theme elements

`element_*()` is used to render the text of theme elements with Typst. By `element_*()`,
you can place rich text, special characters, and math equations in your plot titles,
subtitles, axis titles, legend text, and facet strips.

*Imagine that your `ggplot2` title is a math matrix, while each facet label is the special regression equation!*

```{r element-example}
ggplot(mtcars, aes(wt, mpg, colour = factor(cyl))) +
  geom_point() +
  labs(
    title = r"(`ggplot2` + Typst-rendered theme text)",
    subtitle = r"(Titles and legends can use *Typst markup* directly)",
    x = r"($"X-axis title:" sum_(i=1)^n c_i$)",
    y = r"(\eta = \frac{mpg}{wt})",  # LaTeX math is OK
    colour = r"(_*Cylinders*_)"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_typst(size = 16, face = "bold", colour = "#102A43"),
    plot.subtitle = element_typst(size = 11, colour = "#486581"),
    axis.title.x = element_math_typst(size = 13),
    axis.title.y = element_math_mitex(size = 13, face = "bold"),
    legend.title = element_typst(size = 12),
    legend.text = element_typst(size = 10)  # render legend labels with Typst
  )
```

## Next steps

From here, you can explore:

- the [function reference](https://yousa-mirage.github.io/ggtypst/reference/index.html) for `annotate_*()`, `geom_*()`, and `element_*()`
- the [contributing guide](https://yousa-mirage.github.io/ggtypst/CONTRIBUTING.html) if you want to understand the R/Rust architecture
- and practice `ggtypst` in your RStudio/Positron/VS Code
