## Markdown in Viser

---

Viser has full support for the GFM markdown spec, including **bold**, _italics_,
~~strikethrough~~, and many other features.

Here's a [masked link](https://github.com/nerfstudio-project/viser). Not a fan?
Here's a normal one: https://pypi.org/project/viser/

Anywhere where you can insert GUI elements, you can also insert `images`,
`blockquotes`, `lists`, `tables`, `task lists`, and `(unstyled) code blocks`.

In inline code blocks, you can show off colors with color chips: `#FED363`
`hsl(0, 0%, 82%)` `rgb(255, 255, 255)`

Adding images from a remote origin is simple.

![Viser Logo](https://viser.studio/main/_static/logo.svg)

For local images with relative paths, you can either directly use a
[data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs)
or set the `image_root` argument to the `Path` object that you'd like your paths
relative to. If no such `image_root` is provided, the file system will be scoped
to the directory that Viser is installed in.

![Cal Logo](../examples/assets/Cal_logo.png)

Tables follow the standard markdown spec:

| Application                                          | Description                                        |
| ---------------------------------------------------- | -------------------------------------------------- |
| [NS](https://nerf.studio)                            | A collaboration friendly studio for NeRFs          |
| [Viser](https://nerfstudio-project.github.io/viser/) | An interactive 3D visualization toolbox for Python |

Code blocks, while being not nearly as exciting as some of the things presented,
work as expected. Currently, while you can specify a language and metadata in
your blocks, they will remain unused by the Markdown renderer.

```python
"""Markdown Demonstration

Viser GUI has MDX 2 support.
"""

import time
from pathlib import Path

import viser

server = viser.ViserServer()
server.world_axes.visible = True


@server.on_client_connect
def _(client: viser.ClientHandle) -> None:
    with open("./assets/mdx_example.mdx", "r") as mkdn:
        markdown = client.gui.add_markdown(
            markdown=mkdn.read(), image_root=Path(__file__).parent
        )

    button = client.gui.add_button("Remove Markdown")

    @button.on_click
    def _(_):
        markdown.remove()


while True:
    time.sleep(10.0)
```

As a bonus, MDX is extensible and JS capable. This means that you have the
freedom to do things like:

This page loaded on {(new Date()).toString()}

Or:

> Oh yes, mdx PR would be exciting
>
> <Cite> &#8212; Brent Yi </Cite>

**Note**: Be careful when playing with JSX, it's very easy to break markdown.

So that's MDX in Viser. It has support for:

- [x] CommonMark and GFM standards
  - bold, italics, strikethrough, images, blockquotes, tables, task lists, code
    blocks, inline code
- [x] Color chips
- [x] JSX enhanced components
