## File: README.md

presenterm
===

[![crates-badge]][crates-package] [![brew-badge]][brew-package] [![nix-badge]][nix-package] 
[![arch-badge]][arch-package] [![scoop-badge]][scoop-package] [![winget-badge]][winget-package]

[brew-badge]: https://img.shields.io/homebrew/v/presenterm
[brew-package]: https://formulae.brew.sh/formula/presenterm
[nix-badge]: https://img.shields.io/badge/Packaged_for-Nix-5277C3.svg?logo=nixos&labelColor=73C3D5
[nix-package]: https://search.nixos.org/packages?size=1&show=presenterm
[crates-badge]: https://img.shields.io/crates/v/presenterm
[crates-package]: https://crates.io/crates/presenterm
[arch-badge]: https://img.shields.io/archlinux/v/extra/x86_64/presenterm
[arch-package]: https://archlinux.org/packages/extra/x86_64/presenterm/
[scoop-badge]: https://img.shields.io/scoop/v/presenterm
[scoop-package]: https://scoop.sh/#/apps?q=presenterm&id=a462290f824b50f180afbaa6d8c7c1e6e0952e3a
[winget-badge]: https://img.shields.io/winget/v/mfontanini.presenterm
[winget-package]: https://winstall.app/apps/mfontanini.presenterm

_presenterm_ lets you create presentations in markdown format and run them from your terminal, with support for image 
and animated gifs, highly customizable themes, code highlighting, exporting presentations into PDF format, and plenty of 
other features. This is how the [demo presentation](/examples/demo.md) looks like when running in the [kitty 
terminal](https://sw.kovidgoyal.net/kitty/):



Check the rest of the example presentations in the [examples directory](/examples).

# Documentation

Visit the [documentation][docs-introduction] to get started.

# Features

* Presentations consist of one [or more][docs-include] markdown files.
* [Images and animated gifs][docs-images] on terminals like _kitty_, _iterm2_, _wezterm_, _ghostty_ and _foot_.
* [Customizable themes][docs-themes] including colors, margins, layout (left/center aligned content), footer for every 
  slide, etc. Several [built-in themes][docs-builtin-themes] can give your presentation the look you want without 
  having to define your own.
* Code highlighting for a [wide list of programming languages][docs-code-highlight].
* [Font sizes][docs-font-sizes] for terminals that support them.
* [Selective/dynamic][docs-selective-highlight] code highlighting that only highlights portions of code at a time.
* [Column layouts][docs-layout].
* [mermaid graph rendering][docs-mermaid].
* [d2 graph rendering][docs-d2].
* [_LaTeX_ and _typst_ formula rendering][docs-latex].
* [Introduction slide][docs-intro-slide] that displays the presentation title and your name.
* [Slide titles][docs-slide-titles].
* [Snippet execution][docs-code-execute] for various programming languages, including execution inside pseudo terminals.
* [Export presentations to PDF and HTML][docs-exports].
* [Slide transitions][docs-slide-transitions].
* [Pause][docs-pauses] portions of your slides.
* [Custom key bindings][docs-key-bindings].
* [Automatically reload your presentation][docs-hot-reload] every time it changes for a fast development loop.
* [Define speaker notes][docs-speaker-notes] to aid you during presentations.

See the [introduction page][docs-introduction] to learn more.

# presenterm in action

Here are some talks and demos that feature _presenterm_:

- [If it can compute, it can run Ratatui][it-can-run-ratatui] by [Orhun Parmaksız][orhun-github]
- [Building Embedded TUIs with Rust & Ratatui][building-embedded-tuis] by [Orhun Parmaksız][orhun-github]
- [Bringing Terminal Aesthetics to the Web With Rust][bringing-terminal-aesthetics] by [Orhun Parmaksız][orhun-github]
- [7 Rust Terminal Tools That You Should Use][rust-terminal-tools] by [Orhun Parmaksız][orhun-github]
- [Renaissance of Terminal User Interfaces with Rust][renaissance-tui] by [Orhun Parmaksız][orhun-github]
- [Using Nix on Apple Silicon and declarative development environments][NiXOS-and-Dev] by [pwnwriter][pwnwriter-github]
- [Hayasen: A Robust Embedded Rust Library which supports multiple sensors][hayasen] by [Vaishnav-Sabari-Girish][vaishnav]
- [Using ratatui in Embedded sytems : Meet Mousefood][mousefood] by [Vaishnav-Sabari-Girish][vaishnav]

Gave a talk using _presenterm_? We would love to feature it here! Open a PR or issue to get it added.



[docs-introduction]: https://mfontanini.github.io/presenterm/
[docs-basics]: https://mfontanini.github.io/presenterm/features/introduction.html
[docs-intro-slide]: https://mfontanini.github.io/presenterm/features/introduction.html#introduction-slide
[docs-slide-titles]: https://mfontanini.github.io/presenterm/features/introduction.html#slide-titles
[docs-font-sizes]: https://mfontanini.github.io/presenterm/features/introduction.html#font-sizes
[docs-pauses]: https://mfontanini.github.io/presenterm/features/commands.html#pauses
[docs-images]: https://mfontanini.github.io/presenterm/features/images.html
[docs-include]: https://mfontanini.github.io/presenterm/features/commands.html#including-external-markdown-files
[docs-themes]: https://mfontanini.github.io/presenterm/features/themes/introduction.html
[docs-builtin-themes]: https://mfontanini.github.io/presenterm/features/themes/introduction.html#built-in-themes
[docs-code-highlight]: https://mfontanini.github.io/presenterm/features/code/highlighting.html
[docs-code-execute]: https://mfontanini.github.io/presenterm/features/code/execution.html
[docs-selective-highlight]: https://mfontanini.github.io/presenterm/features/code/highlighting.html#selective-highlighting
[docs-slide-transitions]: https://mfontanini.github.io/presenterm/features/slide-transitions.html
[docs-layout]: https://mfontanini.github.io/presenterm/features/layout.html
[docs-mermaid]: https://mfontanini.github.io/presenterm/features/code/mermaid.html
[docs-d2]: https://mfontanini.github.io/presenterm/features/code/d2.html
[docs-latex]: https://mfontanini.github.io/presenterm/features/code/latex.html
[docs-exports]: https://mfontanini.github.io/presenterm/features/exports.html
[docs-key-bindings]: https://mfontanini.github.io/presenterm/configuration/settings.html#key-bindings
[docs-hot-reload]: https://mfontanini.github.io/presenterm/features/introduction.html#hot-reload
[docs-speaker-notes]: https://mfontanini.github.io/presenterm/features/speaker-notes.html
[bat]: https://github.com/sharkdp/bat
[syntect]: https://github.com/trishume/syntect
[bringing-terminal-aesthetics]: https://www.youtube.com/watch?v=iepbyYrF_YQ
[building-embedded-tuis]: https://www.youtube.com/watch?v=F04kQMKwrwQ
[it-can-run-ratatui]: https://www.youtube.com/watch?v=btqNDDuZ3cI
[rust-terminal-tools]: https://www.youtube.com/watch?v=ATiKwUiqnAU
[renaissance-tui]: https://www.youtube.com/watch?v=hWG51Mc1DlM
[orhun-github]: https://github.com/orhun
[NiXOS-and-Dev]: https://github.com/pwnwriter/PTN11
[pwnwriter-github]: https://github.com/pwnwriter
[hayasen]: https://github.com/Vaishnav-Sabari-Girish/rust_bangalore_oct_2025
[vaishnav]: https://github.com/Vaishnav-Sabari-Girish
[mousefood]: https://github.com/Vaishnav-Sabari-Girish/rust_bangalore_december_2025/

---

## File: docs/src/configuration/introduction.md

# Configuration

_presenterm_ allows you to customize its behavior via a configuration file. This file is stored, along with all of your 
custom themes, in the following directories:

* `$XDG_CONFIG_HOME/presenterm/` if that environment variable is defined, otherwise:
* `~/.config/presenterm/` in Linux.
* `~/Library/Application Support/presenterm/` in macOS.
* `~/AppData/Roaming/presenterm/config/` in Windows.

The configuration file will be looked up automatically in the directories above under the name `config.yaml`. e.g. on 
Linux you should create it under `~/.config/presenterm/config.yaml`. You can also specify a custom path to this file 
when running _presenterm_ via the `--config-file` parameter or the `PRESENTERM_CONFIG_FILE` environment variable.

A [sample configuration file](https://github.com/mfontanini/presenterm/blob/master/config.sample.yaml) is provided in 
the repository that you can use as a base.

# Configuration schema

A JSON schema that defines the configuration file's schema is available to be used with YAML language servers such as
[yaml-language-server](https://github.com/redhat-developer/yaml-language-server).

Include the following line at the beginning of your configuration file to have your editor pull in autocompletion 
suggestions and docs automatically:

```yaml
# yaml-language-server: $schema=https://raw.githubusercontent.com/mfontanini/presenterm/master/config-file-schema.json
```

---

## File: docs/src/configuration/options.md

# Options

Options are special configuration parameters that can be set either in the configuration file under the `options` key, 
or in a presentation's front matter under the same key. This last one allows you to customize a single presentation so 
that it acts in a particular way. This can also be useful if you'd like to share the source files for your presentation 
with other people.

The supported configuration options are currently the following:

## implicit_slide_ends

This option removes the need to use `` in between slides and instead assumes that if you use a slide 
title, then you're implying that the previous slide ended. For example, the following presentation:

```markdown
---
options:
  implicit_slide_ends: true
---

Tasty vegetables
================

* Potato

Awful vegetables
================

* Lettuce
```

Is equivalent to this "vanilla" one that doesn't use implicit slide ends.

```markdown
Tasty vegetables
================

* Potato



Awful vegetables
================

* Lettuce
```

## end_slide_shorthand

This option allows using thematic breaks (`---`) as a delimiter between slides. When enabling this option, you can still 
use `` but any thematic break will also be considered a slide terminator.

```
---
options:
  end_slide_shorthand: true
---

this is a slide

---------------------

this is another slide
```

## h1_slide_titles

This options allows setting whether the first `h1` heading in a slide will automatically become the slide title:

```
---
options:
    h1_slide_titles: true
---

# title

# not the first, so no title
```

## command_prefix

Because _presenterm_ uses HTML comments to represent commands, it is necessary to make some assumptions on _what_ is a 
command and what isn't. The current heuristic is:

* If an HTML comment is laid out on a single line, it is assumed to be a command. This means if you want to use a real 
  HTML comment like ``, this will raise an error.
* If an HTML comment is multi-line, then it is assumed to be a comment and it can have anything inside it. This means 
  you can't have a multi-line comment that contains a command like `pause` inside.

Depending on how you use HTML comments personally, this may be limiting to you: you cannot use any single line comments 
that are not commands. To get around this, the `command_prefix` option lets you configure a prefix that must be set in 
all commands for them to be configured as such. Any single line comment that doesn't start with this prefix will not be 
considered a command.

For example:

```
---
options:
  command_prefix: "cmd:"
---



Tasty vegetables
================

* Potato



**That's it!**
```

In the example above, the first comment is ignored because it doesn't start with "cmd:" and the second one is processed 
because it does.

## incremental_lists

If you'd like all bullet points in all lists to show up with pauses in between you can enable the `incremental_lists` 
option:

```
---
options:
  incremental_lists: true
---

* pauses
* in
* between
```

Keep in mind if you only want specific bullet points to show up with pauses in between, you can use the 
[`incremental_lists` comment command](../features/commands.md#incremental-lists).

## strict_front_matter_parsing

This option tells _presenterm_ you don't care about extra parameters in presentation's front matter. This can be useful 
if you're trying to load a presentation made for another tool. The following presentation would only be successfully 
loaded if you set `strict_front_matter_parsing` to `false` in your configuration file:

```markdown
---
potato: 42
---

# Hi
```

## image_attributes_prefix

The [image size](../features/images.md#image-size) prefix (by default `image:`) can be configured to be anything you 
would want in case you don't like the default one. For example, if you'd like to set the image size by simply doing 
`` you would need to set:

```yaml
---
options:
  image_attributes_prefix: ""
---


```

## auto_render_languages

This option allows indicating a list of languages for which the `+render` attribute can be omitted in their code 
snippets and will be implicitly considered to be set. This can be used for languages like `mermaid` so that graphs are 
always automatically rendered without the need to specify `+render` everywhere.

```yaml
---
options:
  auto_render_languages:
    - mermaid
---
```

## list_item_newlines

The option allows configuring the number of newlines in between list items, the default being `1`. This cam also be set 
via the `list_item_newlines` comment command.

```yaml
---
options:
    list_item_newlines: 2
---
```

---

## File: docs/src/configuration/settings.md

# Settings

As opposed to options, the rest of these settings **can only be configured via the configuration file**.

## Default theme

The default theme can be configured only via the config file. When this is set, every presentation that doesn't set a 
theme explicitly will use this one:

```yaml
defaults:
  theme: light
```

You can also set a dark and light theme independently, _presenterm_ will detect terminal theme on launch by fetching
foreground and background color and pick the right theme:

```yaml
defaults:
  theme:
    light: light
    dark: dark
```

## Terminal font size

This is a parameter that lets you explicitly set the terminal font size in use. This should not be used unless you are 
in Windows, given there's no (easy) way to get the terminal window size so we use this to figure out how large the 
window is and resize images properly. Some terminals on other platforms may also have this issue, but that should not be 
as common.

If you are on Windows or you notice images show up larger/smaller than they should, you can adjust this setting in your 
config file:

```yaml
defaults:
  terminal_font_size: 16
```

## Preferred image protocol

By default _presenterm_ will try to detect which image protocol to use based on the terminal you are using. In case 
detection for some reason fails in your setup or you'd like to force a different protocol to be used, you can explicitly 
set this via the `--image-protocol` parameter or the configuration key `defaults.image_protocol`:

```yaml
defaults:
  image_protocol: kitty-local
```

Possible values are:
* `auto`: try to detect it automatically (default).
* `kitty-local`: use the kitty protocol in "local" mode, meaning both _presenterm_ and the terminal run in the same host 
  and can share the filesystem to communicate.
* `kitty-remote`: use the kitty protocol in "remote" mode, meaning _presenterm_ and the terminal run in different hosts 
  and therefore can only communicate via terminal escape codes.
* `iterm2`: use the iterm2 protocol.
* `sixel`: use the sixel protocol.

## Maximum presentation width

The `max_columns` property can be set to specify the maximum number of columns that the presentation will stretch to. If 
your terminal is larger than that, the presentation will stick to that size and will be centered, preventing it from 
looking too stretched.

```yaml
defaults:
  max_columns: 100
```

If you would like your presentation to be left or right aligned instead of centered when the terminal is too wide, you 
can use the `max_columns_alignment` key:

```yaml
defaults:
  max_columns: 100
  # Valid values: left, center, right
  max_columns_alignment: left
```

## Maximum presentation height

The `max_rows` and `max_rows_alignment` properties are analogous to `max_columns*` to allow capping the maximum number 
of rows:

```yaml
defaults:
  max_rows: 100
  # Valid values: top, center, bottom
  max_rows_alignment: left
```

## Incremental lists behavior

By default, [incremental lists](../features/commands.md) will pause before and after a list. If you would like to change 
this behavior, use the `defaults.incremental_lists` key:

```yaml
defaults:
  incremental_lists:
    # The defaults, change to false if desired.
    pause_before: true
    pause_after: true
```

## Validate terminal overflows

The `validate_overflows` property allows configuring whether _presenterm_ should make sure your presentation fits in the 
current terminal screen. This allows knowing whether any lines are too long to fit in the screen without having to 
scroll through every slide and manually check for that.

When the presentation is first loaded, after the presentation file is modified (if in development mode), and when you 
resize your terminal, _presenterm_ will make sure every slide in it fits. If any of them don't, an error will be 
displayed and you will need to resize your terminal until the error goes away or you exit the program.

This parameter supports multiple options:

* `never`: the default, where overflows aren't validated at all.
* `always`: overflow validation will always happen when running _presenterm_.
* `when_presenting`: only perform validation when in present mode. That is, when you're running `presenterm -p`.
* `when_developing`: only perform validation when running in development mode. That is, any time you're not using 
`presenterm -p`.

```yaml
defaults:
  validate_overflows: always
```

# Slide transitions

Slide transitions allow animating your presentation every time you move from a slide to the next/previous one. The 
configuration for slide transitions is the following:

```yaml
transition:
  # how long the transition should last.
  duration_millis: 750

  # how many frames should be rendered during the transition
  frames: 45

  # the animation to use
  animation:
    style: <style_name>
```

See the [slide transitions page](../features/slide-transitions.md) for more information on which animation styles are 
supported.

# Key bindings

Key bindings that _presenterm_ uses can be manually configured in the config file via the `bindings` key. The following 
is the default configuration:

```yaml
bindings:
  # the keys that cause the presentation to move forwards.
  next: ["l", "j", "<right>", "", "<down>", " "]

  # the keys that cause the presentation to move backwards.
  previous: ["h", "k", "<left>", "", ""]

  # the keys that cause the presentation to move "fast" to the next slide. this will ignore:
  #
  # * Pauses.
  # * Dynamic code highlights.
  # * Slide transitions, if enabled.
  next_fast: ["n"]

  # same as `next_fast` but jumps fast to the previous slide.
  previous_fast: ["p"]

  # the key binding to jump to the first slide.
  first_slide: ["gg"]

  # the key binding to jump to the last slide.
  last_slide: ["G"]

  # the key binding to jump to a specific slide.
  go_to_slide: ["<number>G"]

  # the key binding to execute a piece of shell code.
  execute_code: ["<c-e>"]

  # the key binding to reload the presentation.
  reload: ["<c-r>"]

  # the key binding to toggle the slide index modal.
  toggle_slide_index: ["<c-p>"] 

  # the key binding to toggle the key bindings modal.
  toggle_bindings: ["?"] 

  # the key binding to close the currently open modal.
  close_modal: ["<esc>"]

  # the key binding to close the application.
  exit: ["<c-c>", "q"]

  # the key binding to suspend the application.
  suspend: ["<c-z>"]
```

You can choose to override any of them. Keep in mind these are overrides so if for example you change `next`, the 
default won't apply anymore and only what you've defined will be used.

# Snippet configurations

The configurations that affect code snippets in presentations.

## Snippet execution

[Snippet execution](../features/code/execution.md#executing-code-blocks) is disabled by default for security reasons. 
Besides passing in the `-x` command line parameter every time you run _presenterm_, you can also configure this globally 
for all presentations by setting:

```yaml
snippet:
  exec:
    enable: true
```

**Use this at your own risk**, especially if you're running someone else's presentations!

## Snippet execution + replace

[Snippet execution + replace](../features/code/execution.md#executing-and-replacing) is disabled by default for security 
reasons. Similar to `+exec`, this can be enabled by passing in the `-X` command line parameter or configuring it 
globally by setting:

```yaml
snippet:
  exec_replace:
    enable: true
```

**Use this at your own risk**. This will cause _presenterm_ to execute code without user intervention so don't blindly 
enable this and open a presentation unless you trust its origin!

## Custom snippet executors

If _presenterm_ doesn't support executing code snippets for your language of choice, please [create an 
issue](https://github.com/mfontanini/presenterm/issues/new)! Alternatively, you can configure this locally yourself by 
setting:

```yaml
snippet:
  exec:
    custom:
      # The keys should be the language identifier you'd use in a code block.
      c++:
        # The name of the file that will be created with your snippet's contents.
        filename: "snippet.cpp"

        # A list of environment variables that should be set before building/running your code.
        environment:
          MY_FAVORITE_ENVIRONMENT_VAR: foo

        # A prefix that indicates a line that starts with it should not be visible but should be executed if the
        # snippet is marked with `+exec`.
        hidden_line_prefix: "/// "

        # A list of commands that will be ran one by one in the same directory as the snippet is in.
        commands:
          # Compile if first
          - ["g++", "-std=c++20", "snippet.cpp", "-o", "snippet"]
          # Now run it 
          - ["./snippet"]
```

The output of all commands will be included in the code snippet execution output so if a command (like the `g++` 
invocation) was to emit any output, make sure to use whatever flags are needed to mute its output.

Also note that you can override built-in executors in case you want to run them differently (e.g. use `c++23` in the 
example above).

See more examples in the [executors.yaml](https://github.com/mfontanini/presenterm/blob/master/executors.yaml) file 
which defines all of the built-in executors. 

## Snippet rendering threads

Because some `+render` code blocks can take some time to be rendered into an image, especially if you're using 
[mermaid](https://mermaid.js.org/) charts, this is run asychronously. The number of threads used to render these, which 
defaults to 2, can be configured by setting:

```yaml
snippet:
  render:
    threads: 2
```

## Mermaid

The following configuration parameters can be set to alter the behavior when displaying 
[mermaid](https://mermaid.js.org/) diagrams.

### Config file

A custom [mermaid config file](https://mermaid.ai/open-source/config/schema-docs/config.html) can be configured via the 
`mermaid.config_file` config parameter. This should point to a configuration file where you can set any configs you 
consider appropriate, such as the font family to use:

```yaml
mermaid:
  config_file: /home/foo/my_config_file.yml
```

### Puppeteer config file

A custom puppeteer config file can be configured via the `mermaid.puppeteer_config_file` config parameter. This should 
point to a configuration file that will be given to puppeteer by the `mmdc` tool:

```yaml
mermaid:
  puppeteer_config_file: /home/foo/puppeteer.json
```

### Scaling

mermaid graphs will use a default scaling of `2` when invoking the mermaid CLI. If you'd like to change this use:


```yaml
mermaid:
  scale: 2
```

## D2 scaling

[d2](https://d2lang.com/) graphs will use the default scaling when invoking the d2 CLI. If you'd like to change this 
use:


```yaml
d2:
  scale: 2
```

## Enabling speaker note publishing

If you don't want to run _presenterm_ with `--publish-speaker-notes` every time you want to publish speaker notes, you 
can set the `speaker_notes.always_publish` attribute to `true`.

```yaml
speaker_notes:
  always_publish: true
```

# Presentation exports

The configurations that affect PDF and HTML exports.

## Export size

By default, the size of each page in the generated PDF and HTML files will depend on the size of your terminal. 

If you would like to instead configure the dimensions by hand, set the `export.dimensions` key:

```yaml
export:
  dimensions:
    columns: 80
    rows: 30
```

## Pause behavior

By default pauses will be ignored in generated PDF files. If instead you'd like every pause to generate a new page in 
the export, set the `export.pauses` attribute:

```yaml
export:
  pauses: new_slide
```

## Sequential snippet execution

When generating exports, snippets are executed in parallel to make the process faster. If your snippets require being 
executed sequentially, you can use the `export.snippets` parameter:

```yaml
export:
  snippets: sequential
```

## PDF font 

The PDF export can be configured to use a specific font installed in your system. Use the following keys to do so:

```yaml
export:
  pdf:
    fonts:
      normal: /usr/share/fonts/truetype/tlwg/TlwgMono.ttf
      italic: /usr/share/fonts/truetype/tlwg/TlwgMono-Oblique.ttf
      bold: /usr/share/fonts/truetype/tlwg/TlwgMono-Bold.ttf
      bold_italic: /usr/share/fonts/truetype/tlwg/TlwgMono-BoldOblique.ttf
```

---

## File: docs/src/features/code/execution.md

# Snippet execution

## Executing code blocks

Annotating a code block with a `+exec` attribute will make it executable. Pressing `control+e` when viewing a slide that 
contains an executable block, the code in the snippet will be executed and the output of the execution will be displayed 
on a box below it. The code execution is stateful so if you switch to another slide and then go back, you will still see 
the output.

~~~markdown
```bash +exec
echo hello world
```
~~~

Code execution **must be explicitly enabled** by using either:

* The `-x` command line parameter when running _presenterm_.
* Setting the `snippet.exec.enable` property to `true` in your [_presenterm_ config 
file](../../configuration/settings.md#snippet-execution).

Refer to [the table in the highlighting page](highlighting.md#code-highlighting) for the list of languages for which 
code execution is supported.

---

[](https://asciinema.org/a/BbAY817esxagCgPtnKUwgYnHr)

> [!warning]
> Run code in presentations at your own risk! Especially if you're running someone else's presentation. Don't blindly 
> enable snippet execution!

### Output placing

By default a snippet's output will always show up right below the snippet. However, if you wanted to show the output in 
a different place in a slide (e.g. another column) or even in another slide you can do this by:

1. Defining a snippet's identifier:

~~~markdown
```bash +exec +id:foo
echo hellow world
```
~~~

2. Referencing that identifier where you want the output to appear by using the `snippet_output` comment command:

~~~markdown

~~~

A single snippet can be referenced multiple times in multiple slides, as long as the slide you're referencing it in 
comes after the snippet. The snippet will only be executed once, and every `snippet_output` command will display that 
single execution's output.

### Validating snippets

While you're developing your presentation you probably want to make sure the executable snippets you write in it are 
correct and don't contain any syntax errors. While you can do this by constantly pressing `<c-e>` every time you change 
a snippet, this is automatically done by _presenterm_ if you pass in the `--validate-snippets` flag.

When you pass in this flag, _presenterm_ will:

* Automatically run all `+exec`, `+exec_replace`, and `+validate` snippets as soon as your presentation starts. Note 
that the `+validate` flag is a special one that doesn't make a snippet executable but still validates it by running it 
during development.
* Report an error if any of the snippets returns an exit code other than 0.
* Re-run all snippets `+exec` and `+exec_replace` snippets every time the presentation is reloaded.

In case you expect a snippet to return an exit code other than 0, you can use the `+expect:failure` flag. This will 
cause _presenterm_ to display an error if the snippet does not fail.

For example, the following defines a snippet that's not executable but that will be validated if `--validate-snippets` 
is passed in and will display an error if the snippet does not fail.

```rust +validate +expect:failure
fn main() {
    let q = 42;
    let w = q + "foo"; // oops
}
```

## Running code in pseudo terminal (PTY)

By using the `+pty` attribute, you can run a code snippet inside a pseudo terminal. This allows running tools like `top` 
and `htop` which move the cursor around, clear the screen, etc, and have them behave how you'd expect.

[](https://asciinema.org/a/PWdPtehxI6xwM7Yt)

Note that this can be used with snippets in any language, not necessarily only shell scripts. 

> [!note]
> Support for sending keyboard input into running scripts is planned but not currently supported.

### Specifying PTY size

The size of the PTY used to execute the code will be expanded to fit the screen. A custom size can be set by using the 
`+pty:<columns>:<rows>` syntax, e.g. `+pty:80:30`.

### Standby mode

A `+pty:standby` block indicates the area of the slide the PTY will be rendered on should always be visible, even before 
the code is executed. Note that if you're also configuring the PTY size, the syntax is `+pty:standby:<columns>:<rows>` 

[](https://asciinema.org/a/IrclITxMSkBZPPH3)

## Executing and replacing

Similar to `+exec`, `+exec_replace` causes a snippet to be executable but:

* Execution happens automatically without user intervention.
* The snippet will be automatically replaced with its execution output.

This can be useful to run programs that generate some form of ASCII art that you'd like to generate dynamically.

[](https://asciinema.org/a/hklQARZKb5sP5mavL4cGgbYXD)

Because of the risk involved in `+exec_replace`, where code gets automatically executed when running a presentation, 
this requires users to explicitly opt in to it. This can be done by either passing in the `-X` command line parameter
or setting the `snippet.exec_replace.enable` flag in your configuration file to `true`.

## Automatic execution

The `+auto_exec` property behaves like a `+exec` code block but doesn't require pressing `<c-e>` to execute it.

## Alternative executors

Some languages support alternative executors. For example, `rust` code can be ran via 
[`rust-script`](https://rust-script.org/), which allows you to use external crates. These executors can be used by 
specifying `:<executor-name>` after `+exec` or `+exec_replace`.

For example, the following `rust` snippet will be executed using `rust-script`:

~~~markdown
```rust +exec:rust-script
# //! ```cargo
# //! [dependencies]
# //! time = "0.1.25"
# //! ```
# // The lines above will be hidden
fn main() {
    println!("the time is {}", time::now().rfc822z());
}
```
~~~

The supported alternative executors are:

* `rust-script` for `rust` snippets.
* `pytest` and `uv` for `python` snippets.

## Code to image conversions

The `+image` attribute behaves like `+exec_replace` but also assumes the output of the executed snippet will be an 
image, and it will render it as such. For this to work, the code **must only emit an image in jpg/png formats** and 
nothing else.

For example, this would render the demo presentation's image:

~~~markdown
```bash +image
cat examples/doge.png
```
~~~

This attribute carries the same risks as `+exec_replace` and therefore needs to be enabled via the same flags.

## Executing snippets that need a TTY

If you're trying to execute a program like `top` that needs to run on a TTY as it renders text, clears the screen, etc, 
you can use the `+acquire_terminal` modifier on a code already marked as executable with `+exec`. Executing snippets 
tagged with these two attributes will cause _presenterm_ to suspend execution, the snippet will be invoked giving it the 
raw terminal to do whatever it needs, and upon its completion _presenterm_ will resume its execution.

[](https://asciinema.org/a/AHfuJorCNRR8ZEnfwQSDR5vPT)

## Styled execution output

Snippets that generate output which contains escape codes that change the colors or styling of the text will be parsed 
and displayed respecting those styles. Do note that you may need to force certain tools to use colored output as they 
will likely not use it by default.

For example, to get colored output when invoking `ls` you can use:

~~~markdown
```bash +exec
ls /tmp --color=always
```
~~~

The parameter or way to enable this will depend on the tool being invoked.

## Hiding code lines

When you mark a code snippet as executable via the `+exec` flag, you may not be interested in showing _all the lines_ to 
your audience, as some of them may not be necessary to convey your point. For example, you may want to hide imports, 
non-essential functions, initialization of certain variables, etc. For this purpose, _presenterm_ supports a prefix 
under certain programming languages that let you indicate a line should be executed when running the code but should not 
be displayed in the presentation.

For example, in the following code snippet only the print statement will be displayed but the entire snippet will be 
ran:

~~~markdown
```rust
# fn main() {
println!("Hello world!");
# }
```
~~~

Rather than blindly relying on a prefix that may have a meaning in a language, prefixes are chosen on a per language 
basis. The languages that are supported and their prefix is:

* rust: `# `.
* python/bash/fish/shell/zsh/kotlin/java/javascript/typescript/c/c++/go: `/// `.

This means that any line in a rust code snippet that starts with `# ` will be hidden, whereas all lines in, say, a 
golang code snippet that starts with a `/// ` will be hidden.

## Pre-rendering 

Some languages support pre-rendering. This means the code block is transformed into something else when the presentation 
is loaded. The languages that currently support this are _mermaid_, _LaTeX_, and _typst_ where the contents of the code 
block is transformed into an image, allowing you to define formulas as text in your presentation. This can be done by 
using the `+render` attribute on a code block.

See the [LaTeX and typst](latex.md), [mermaid](mermaid.md), and [d2](d2.md) docs for more information.

---

## File: docs/src/features/code/highlighting.md

# Code highlighting

Code highlighting is supported for the following languages:

| Language    | Execution support |
|-------------|-------------------|
| ada         |                   |
| asp         |                   |
| awk         |                   |
| bash        |         ✓         |
| cmd         |         ✓         |
| C           |         ✓         |
| cmake       |                   |
| crontab     |                   |
| C#          |         ✓         |
| clojure     |                   |
| C++         |         ✓         |
| CSS         |                   |
| D           |                   |
| dart        |                   |
| diff        |                   |
| docker      |                   |
| dotenv      |                   |
| elixir      |         ✓         |
| elm         |                   |
| erlang      |                   |
| fish        |         ✓         |
| F#          |         ✓         |
| gdscript    |                   |
| go          |         ✓         |
| graphql     |                   |
| haskell     |         ✓         |
| HTML        |                   |
| java        |         ✓         |
| javascript  |         ✓         |
| json        |                   |
| jsonnet     |         ✓         |
| julia       |         ✓         |
| kotlin      |         ✓         |
| latex       |                   |
| lua         |         ✓         |
| makefile    |                   |
| markdown    |                   |
| nix         |                   |
| ocaml       |                   |
| perl        |         ✓         |
| php         |         ✓         |
| powershell  |         ✓         |
| protobuf    |                   |
| puppet      |                   |
| python      |         ✓         |
| R           |         ✓         |
| racket      |                   |
| ruby        |         ✓         |
| rust        |         ✓         |
| scala       |                   |
| shell       |         ✓         |
| sql         |                   |
| swift       |                   |
| svelte      |                   |
| tcl         |                   |
| toml        |                   |
| terraform   |                   |
| typescript  |         ✓         |
| tsx         |         ✓         |
| verilog     |                   |
| vue         |                   |
| wsl         |         ✓         |
| xml         |                   |
| yaml        |                   |
| zig         |                   |
| zsh         |         ✓         |

Other languages that are supported are:

* nushell, for which highlighting isn't supported but execution is.

If there's a language that is not in this list and you would like it to be supported, please [create an 
issue](https://github.com/mfontanini/presenterm/issues/new). If you'd also like code execution support, provide details 
on how to compile (if necessary) and run snippets for that language. You can also configure how to run code snippet for 
a language locally in your [config file](../../configuration/settings.md#custom-snippet-executors).

## Enabling line numbers

If you would like line numbers to be shown on the left of a code block use the `+line_numbers` switch after specifying
the language in a code block:

~~~markdown
```rust +line_numbers
   fn hello_world() {
       println!("Hello world");
   }
```
~~~

## Selective highlighting

By default, the entire code block will be syntax-highlighted. If instead you only wanted a subset of it to be
highlighted, you can use braces and a list of either individual lines, or line ranges that you'd want to highlight.

~~~markdown
```rust {1,3,5-7}
   fn potato() -> u32 {         // 1: highlighted
                                // 2: not highlighted
       println!("Hello world"); // 3: highlighted
       let mut q = 42;          // 4: not highlighted
       q = q * 1337;            // 5: highlighted
       q                        // 6: highlighted
   }                            // 7: highlighted
```
~~~

## Dynamic highlighting

Similar to the syntax used for selective highlighting, dynamic highlighting will change which lines of the code in a
code block are highlighted every time you move to the next/previous slide.

This is achieved by using the separator `|` to indicate what sections of the code will be highlighted at a given time.
You can also use `all` to highlight all lines for a particular frame.

~~~markdown
```rust {1,3|5-7}
   fn potato() -> u32 {

       println!("Hello world");
       let mut q = 42;
       q = q * 1337;
       q
   }
```
~~~

In this example, lines 1 and 3 will be highlighted initially. Then once you press a key to move to the next slide, lines
1 and 3 will no longer be highlighted and instead lines 5 through 7 will. This allows you to create more dynamic
presentations where you can display sections of the code to explain something specific about each of them.

See this real example of how this looks like.

[](https://asciinema.org/a/iCf4f6how1Ux3H8GNzksFUczI)

## Including external code snippets

The `file` snippet type can be used to specify an external code snippet that will be included and highlighted as usual. 

~~~markdown
```file +exec +line_numbers
path: snippet.rs
language: rust
```
~~~

If you'd like to include only a subset of the file, you can use the optional fields `start_line` and `end_line`:

~~~markdown
```file +exec +line_numbers
path: snippet.rs
language: rust
# Only show lines 5-10
start_line: 5
end_line: 10
```
~~~

## Showing a snippet without a background

Using the `+no_background` flag will cause the snippet to have no background. This is useful when combining it with the 
`+exec_replace` flag described further down.

## Adding highlighting syntaxes for new languages

_presenterm_ uses the syntaxes supported by [bat](https://github.com/sharkdp/bat) to highlight code snippets, so any 
languages supported by _bat_ natively can be added to _presenterm_ easily. Please create a ticket or use 
[this](https://github.com/mfontanini/presenterm/pull/385) as a reference to submit a pull request to make a syntax 
officially supported by _presenterm_ as well.

If a language isn't natively supported by _bat_ but you'd like to use it, you can follow
[this guide in the bat docs](https://github.com/sharkdp/bat#adding-new-syntaxes--language-definitions) and
invoke _bat_ directly in a presentation:

~~~markdown
```bash +exec_replace
bat --color always script.py
```
~~~

> [!note]
> Check the [code execution docs](execution.md#executing-and-replacing) for more details on how to allow the tool to run 
> `exec_replace` blocks.

---

## File: docs/src/features/code/latex.md

# LaTeX and typst

`latex` and `typst` code blocks can be marked with the `+render` attribute (see [highlighting](highlighting.md)) to have 
them rendered into images when the presentation is loaded. This allows you to define formulas in text rather than having 
to define them somewhere else, transform them into an image, and them embed it.

For example, the following presentation:

~~~
# Formulas

```latex +render
\[ \sum_{n=1}^{\infty} 2^{-n} = 1 \]
```
~~~

Would be rendered like this:



## Dependencies

### typst

The engine used to render both of these languages is [typst](https://github.com/typst/typst). _typst_ is easy to 
install, lightweight, and boilerplate free as compared to _LaTeX_.

### pandoc

For _LaTeX_ code rendering both _typst_ and [pandoc](https://github.com/jgm/pandoc) are required. How this works is the 
_LaTeX_ code you write gets transformed into _typst_ code via _pandoc_ and then rendered by using _typst_. This lets us:

* Have the same look/feel on generated formulas for both languages.
* Avoid having to write lots of boilerplate _LaTeX_ to make rendering for that language work.
* Have the same logic to render formulas for both languages, except with a small preparation step for _LaTeX_.

## Controlling PPI

_presenterm_ lets you define how many Pixels Per Inch (PPI) you want in the generated images. This is important because 
as opposed to images that you manually include in your presentation, where you control the exact dimensions, the images 
generated on the fly will have a fixed size. Configuring the PPI used during the conversion can let you adjust this: the 
higher the PPI, the larger the generated images will be.

Because as opposed to most configurations this is a very environment-specific config, the PPI parameter is not part of 
the theme definition but is instead has to be set in _presenterm_'s [config file](../../configuration/introduction.md):

```yaml
typst:
  ppi: 400
```

The default is 300 so adjust it and see what works for you.

## Image paths

If you're including an image inside a _typst_ snippet, you must:

* Use absolute paths, e.g. `#image("/image1.png")`.
* Place the image in the same or a sub path of the path where the presentation is. That is, if your presentation file is 
at `/tmp/foo/presentation.md`, you can place images in `/tmp/foo`, and `/tmp/foo/bar` but not under `/tmp/bar`. This is 
because of the absolute path rule above: the path will be considered to be relative to the presentation file's 
directory.

## Controlling the image size

You can also set the generated image's size on a per code snippet basis by using the `+width` modifier which specifies 
the width of the image as a percentage of the terminal size.

~~~markdown
```typst +render +width:50%
$f(x) = x + 1$
```
~~~

## Customizations

The colors and margin of the generated images can be defined in your theme:

```yaml
typst:
  colors:
    background: ff0000
    foreground: 00ff00

  # In points
  horizontal_margin: 2
  vertical_margin: 2
```

---

## File: docs/src/features/code/mermaid.md

## Mermaid

[mermaid](https://mermaid.js.org/) snippets can be converted into images automatically in any code snippet tagged with 
the `mermaid` language and a `+render` tag:

~~~markdown
```mermaid +render
sequenceDiagram
    Mark --> Bob: Hello!
    Bob --> Mark: Oh, hi mark!
```
~~~

**This requires having [mermaid-cli](https://github.com/mermaid-js/mermaid-cli) installed**.

Note that because the mermaid CLI will spin up a browser under the hood, this may not work in all environments and can 
also be a bit slow (e.g. ~2 seconds to generate every image). Mermaid graphs are rendered asynchronously by a number of 
threads that can be configured in the [configuration file](../../configuration/settings.md#snippet-rendering-threads). 
This configuration value currently defaults to 2.

The size of the rendered image can be configured by changing:
* The `mermaid.scale` [configuration parameter](../../configuration/settings.md#mermaid-scaling).
* Using the `+width:<number>%` attribute in the code snippet.

For example, this diagram will take up 50% of the width of the window and will preserve its aspect ratio:

~~~markdown
```mermaid +render +width:50%
sequenceDiagram
    Mark --> Bob: Hello!
    Bob --> Mark: Oh, hi mark!
```
~~~

It is recommended to change the `mermaid.scale` parameter until images look big enough and then adjust on an image by 
image case if necessary using the `+width` attribute. Otherwise, using a small scale and then scaling via `+width` may 
cause the image to become blurry.

## Theme

The theme of the rendered mermaid diagrams can be changed through the following [theme](../themes/introduction.md) 
parameters:

* `mermaid.background` the background color passed to the CLI (e.g., `transparent`, `red`, `#F0F0F0`).
* `mermaid.theme` the [mermaid theme](https://mermaid.js.org/config/theming.html#available-themes) to use.

## Always render diagrams

If you don't want to use `+render` every time, you can configure which languages get this automatically via the [config 
file](../../configuration/settings.md#auto_render_languages).

---

## File: docs/src/features/themes/definition.md

# Theme definition

This section goes through the structure of the theme files. Have a look at some of the [existing 
themes](https://github.com/mfontanini/presenterm/tree/master/themes) to have an idea of how to structure themes. 

## Root elements

The root attributes on the theme yaml files specify either:

* A specific type of element in the input markdown or rendered presentation. That is, the slide title, headings, footer, 
  etc.
* A default to be applied as a fallback if no specific style is specified for a particular element.

## Alignment

_presenterm_ uses the notion of alignment, just like you would have in a GUI editor, to align text to the left, center, 
or right. You probably want most elements to be aligned left, _some_ to be aligned on the center, and probably none to 
the right (but hey, you're free to do so!).

The following elements support alignment:
* Code blocks.
* Slide titles.
* The title, subtitle, and author elements in the intro slide.
* Tables.

### Left/right alignment

Left and right alignments take a margin property which specifies the number of columns to keep between the text and the 
left/right terminal screen borders. 

The margin can be specified in two ways:

#### Fixed

A specific number of characters regardless of the terminal size.

```yaml
alignment: left
margin:
  fixed: 5
```

#### Percent

A percentage over the total number of columns in the terminal.

```yaml
alignment: left
margin:
  percent: 8
```

Percent alignment tends to look a bit nicer as it won't change the presentation's look as much when the terminal size 
changes.

### Center alignment

Center alignment has 2 properties:
* `minimum_size` which specifies the minimum size you want that element to have. This is normally useful for code blocks 
  as they have a predefined background which you likely want to extend slightly beyond the end of the code on the right.
* `minimum_margin` which specifies the minimum margin you want, using the same structure as `margin` for left/right 
  alignment. This doesn't play very well with `minimum_size` but in isolation it specifies the minimum number of columns 
  you want to the left and right of your text.

## Colors

Every element can have its own background/foreground color using hex notation:

```yaml
default:
  colors:
    foreground: ff0000
    background: 00ff00
```

## Default style

The default style specifies:

* The margin to be applied to all slides.
* The colors to be used for all text.

```yaml
default:
  margin:
    percent: 8
  colors:
    foreground: "e6e6e6"
    background: "040312"
```

## Intro slide

The introductory slide will be rendered if you specify a title, subtitle, or author in the presentation's front matter. 
This lets you have a less markdown-looking introductory slide that stands out so that it doesn't end up looking too 
monotonous:

```yaml
---
title: Presenting from my terminal
sub_title: Like it's 1990
author: John Doe
---
```

The theme can specify:
* For the title and subtitle, the alignment and colors.
* For the author, the alignment, colors, and positioning (`page_bottom` and `below_title`). The first one will push it 
  to the bottom of the screen while the second one will put it right below the title (or subtitle if there is one)

For example:

```yaml
intro_slide:
  title:
    alignment: left
    margin:
      percent: 8
  author:
    colors:
      foreground: black
    positioning: below_title
```

## Footer

The footer currently comes in 3 flavors:

### Template footers

A template footer lets you put text on the left, center and/or right of the screen. The template strings
can reference `{current_slide}` and `{total_slides}` which will be replaced with the current and total number of slides.

Besides those special variables, any of the attributes defined in the front matter can also be used:

* `title`.
* `sub_title`.
* `event`.
* `location`.
* `date`.
* `author`.

Strings used in template footers can contain arbitrary markdown, including `span` tags that let you use colored text. A 
`height` attribute allows specifying how tall, in terminal rows, the footer is. The text in the footer will always be 
placed at the center of the footer area. The default footer height is 2.

```yaml
footer:
  style: template
  left: "My **name** is {author}"
  center: "_@myhandle_"
  right: "{current_slide} / {total_slides}"
  height: 3
```

Do note that:

* Only existing attributes in the front matter can be referenced. That is, if you use `{date}` but the `date` isn't set, 
an error will be shown.
* Similarly, referencing unsupported variables (e.g. `{potato}`) will cause an error to be displayed. If you'd like the 
`{}` characters to be used in contexts where you don't want to reference a variable, you will need to escape them by 
using another brace. e.g. `{{potato}} farms` will be displayed as `{potato} farms`.

#### Footer images

Besides text, images can also be used in the left/center/right positions. This can be done by specifying an `image` key 
under each of those attributes:

```yaml
footer:
  style: template
  left:
    image: potato.png
  center:
    image: banana.png
  right:
    image: apple.png
  # The height of the footer to adjust image sizes
  height: 5
```

Images will be looked up:

* First, relative to the presentation file just like any other image.
* If the image is not found, it will be looked up relative to the themes directory. e.g. `~/.config/presenterm/themes`. 
This allows you to define a custom theme in your themes directory that points to a local image within that same 
location.

Images will preserve their aspect ratio and expand vertically to take up as many terminal rows as `footer.height` 
specifies. This parameter should be adjusted accordingly if taller-than-wider images are used in a footer.

See the [footer example](https://github.com/mfontanini/presenterm/blob/master/examples/footer.md) as a showcase of how a 
footer can contain images and colored text.



### Progress bar footers

A progress bar that will advance as you move in your presentation. This will by default use a block-looking character to 
draw the progress bar but you can customize it:

```yaml
footer:
  style: progress_bar

  # Optional!
  character: 🚀
```

### None

No footer at all!

```yaml
footer:
  style: empty
```


## Slide title

Slide titles, as specified by using a setext header, can be styled the following way:

```yaml
slide_title:
  # The prefix to use for the slide title.
  prefix: "██"

  # The font size to use.
  font_size: 2

  # The vertical padding added before the title.
  padding_top: 1

  # The vertical padding added after the title.
  padding_bottom: 1

  # Whether to use a horizontal separator line after the title.
  separator: true

  # Whether to style for the title using bold text.
  bold: true

  # Whether to style for the title using underlined text.
  underlined: true

  # Whether to style for the title using italics text.
  italics: true

  # The colors to use.
  colors:
    foreground: beeeff
    background: feeedd
```

## Headings

Every header type (h1 through h6) can have its own style. Each of them can be styled using the following attributes:

```yaml
headings:
  # H1 style.
  h1:
    # The prefix to use for the heading
    prefix: "██"

    # The colors to use.
    colors:
      foreground: beeeff
      background: feeedd
    # Whether to style for the title using bold text.
    bold: true

    # Whether to style for the title using underlined text.
    underlined: true

    # Whether to style for the title using italics text.
    italics: true
  
  # H2 style, same as the keys for H1.
  h2:
    prefix: "▓▓▓"
    colors:
      foreground: feeedd
```

## Code blocks

The syntax highlighting for code blocks is done via the [syntect](https://github.com/trishume/syntect) crate. The list 
of all the supported themes is the following:

* base16-ocean.dark
* base16-eighties.dark
* base16-mocha.dark
* base16-ocean.light
* Catppuccin
* Coldark
* DarkNeon
* InspiredGitHub
* Nord-sublime
* Solarized
* Solarized (dark)
* Solarized (light)
* TwoDark
* dracula-sublime
* github-sublime-theme
* gruvbox
* onehalf
* sublime-monokai-extended
* sublime-snazzy
* visual-studio-dark-plus
* zenburn

Most of these are taken from the [bat tool](https://github.com/sharkdp/bat), thanks to the people behind `bat` for 
implementing them!

Code blocks can also have a few additional properties:

```yaml
code:
  # The code theme.
  theme_name: base16-eighties.dark

  # The padding to be applied, in cells, around a code snippet.
  padding:
    horizontal: 2
    vertical: 1

  # Whether the theme's background color should be used around the code block.
  background: false

  # Whether to set line numbers in all snippets by default.
  line_numbers: false
```

#### Custom highlighting themes

Besides the built-in highlighting themes, you can drop any `.tmTheme` theme in the `themes/highlighting` directory under 
your [configuration directory](../../configuration/introduction.md) (e.g. `~/.config/presenterm/themes/highlighting` in 
Linux) and they will be loaded automatically when _presenterm_ starts.

## Block quotes

For block quotes you can specify a string to use as a prefix in every line of quoted text:

```yaml
block_quote:
  prefix: "▍ "
```

## Mermaid

The [mermaid](https://mermaid.js.org/) graphs can be customized using the following parameters:

* `mermaid.background` the background color passed to the CLI (e.g., `transparent`, `red`, `#F0F0F0`).
* `mermaid.theme` the [mermaid theme](https://mermaid.js.org/config/theming.html#available-themes) to use.

```yaml
mermaid:
  background: transparent
  theme: dark
```

## Alerts

GitHub style markdown alerts can be styled by setting the `alert` key:

```yaml
alert:
  # the base colors used in all text in an alert
  base_colors:
    foreground: red
    background: black

  # the prefix used in every line in the alert
  prefix: "▍ "

  # the style for each alert type
  styles:
    note:
      color: blue
      title: Note
      icon: I
    tip:
      color: green
      title: Tip
      icon: T
    important:
      color: cyan
      title: Important
      icon: I
    warning:
      color: orange
      title: Warning
      icon: W
    caution:
      color: red
      title: Caution
      icon: C
```

## Extending themes

Custom themes can extend other custom or built in themes. This means it will inherit all the properties of the theme 
being extended by default.

For example:

```yaml
extends: dark
default:
  colors:
    background: "000000"
```

This theme extends the built in _dark_ theme and overrides the background color. This is useful if you find yourself 
_almost_ liking a built in theme but there's only some properties you don't like.

## Color palette

Every theme can define a color palette, which includes a list of pre-defined colors and a list of background/foreground 
pairs called "classes". Colors and classes can be used when styling text via `` HTML tags, whereas colors can also 
be used inside themes to avoid duplicating the same colors all over the theme definition.

A palette can de defined as follows:

```yaml
palette:
  colors:
    red: "f78ca2"
    purple: "986ee2"
  classes:
    foo:
      foreground: "ff0000"
      background: "00ff00"
```

Any palette color can be referenced using either `palette:<name>` or `p:<name>`. This means now any part of the theme 
can use `p:red` and `p:purple` where a color is required.

Similarly, these colors can be used in `span` tags like:

```html
this is red

this is foo-colored
```

These colors can used anywhere in your presentation as well as in other places such as in
[template footers](#template-footers) and [introduction slides](../introduction.md#introduction-slide).

## Bold/italics styling

Bold and italics text is not given any colors by default. The `bold` and `italics` top level keys can be used to define 
a set of colors to use for them:

```yaml
bold:
  colors:
    foreground: red
italics:
  colors:
    background: blue
```

---

## File: docs/src/features/themes/introduction.md

# Themes

_presenterm_ tries to be as configurable as possible, allowing users to create presentations that look exactly how they 
want them to look like. The tool ships with a set of [built-in 
themes](https://github.com/mfontanini/presenterm/tree/master/themes) but users can be created by users in their local 
setup and imported in their presentations.

## Setting themes

There's various ways of setting the theme you want in your presentation:

### CLI

Passing in the `--theme` parameter when running _presenterm_ to select one of the built-in themes.

### Within the presentation

The presentation's markdown file can contain a front matter that specifies the theme to use. This comes in 3 flavors:

#### By name

Using a built-in theme name makes your presentation use that one regardless of what the default or what the `--theme` 
option specifies:

```yaml
---
theme:
  name: dark
---
```

Built-in light/dark theme detection allows you to define a different theme for each variant:


```yaml
---
theme:
  # The theme used if your terminal is using light colors.
  light: light

  # The theme used if your terminal is using dark colors.
  dark: dark
---
```

#### By path

You can define a theme file in yaml format somewhere in your filesystem and reference it within the presentation:

```yaml
---
theme:
  path: /home/me/Documents/epic-theme.yaml
---
```

#### Overrides

You can partially/completely override the theme in use from within the presentation:

```yaml
---
theme:
  override:
    default:
      colors:
        foreground: "beeeff"
---
```

This lets you:

1. Create a unique style for your presentation without having to go through the process of taking an existing theme, 
   copying somewhere, and changing it when you only expect to use it for that one presentation.
2. Iterate quickly on styles given overrides are reloaded whenever you save your presentation file.

# Built-in themes

A few built-in themes are bundled with the application binary, meaning you don't need to have any external files 
available to use them. These are packed as part of the [build 
process](https://github.com/mfontanini/presenterm/blob/master/build.rs) as a binary blob and are decoded on demand only
when used.

Currently, the following themes are supported:

* A set of themes based on the [catppuccin](https://github.com/catppuccin/catppuccin) color palette:
  * `catppuccin-latte`
  * `catppuccin-frappe`
  * `catppuccin-macchiato`
  * `catppuccin-mocha`
* `dark`: A dark theme.
* `gruvbox-dark`: A theme inspired by the colors used in [gruvbox](https://github.com/morhetz/gruvbox).
* `light`: A light theme.
* `terminal-dark`: A theme that uses your terminals color and looks best if your terminal uses a dark color scheme. This 
means if your terminal background is e.g. transparent, or uses an image, the presentation will inherit that.
* `terminal-light`: The same as `terminal-dark` but works best if your terminal uses a light color scheme.
* A set of themes based on the [toyonight](https://github.com/folke/tokyonight.nvim) color palette:
    * `tokyonight-moon`
    * `tokyonight-day`
    * `tokyonight-night`
    * `tokyonight-storm`

## Trying out built-in themes

All built-in themes can be tested by using the `--list-themes` parameter:

```bash
presenterm --list-themes
```

This will run a presentation where the same content is rendered using a different theme in each slide:

[](https://asciinema.org/a/zeV1QloyrLkfBp6rNltvX7Lle)

# Loading custom themes

On startup, _presenterm_ will look into the `themes` directory under the [configuration 
directory](../../configuration/introduction.md) (e.g. `~/.config/presenterm/themes` in Linux) and will load any `.yaml` 
file as a theme and make it available as if it was a built-in theme. This means you can use it as an argument to the 
`--theme` parameter, use it in the `theme.name` property in a presentation's front matter, etc.