# Sphinx + MyST + Markdown for Static HTML Pages
This vignette covers the combination of `Sphinx`, `Markdown`, and `MyST` to create static `HTML` pages. `Sphinx` is an open-source documentation generator that can easily integrate with `Markdown` via `MyST`. `Markdown` is the lightweight markup language that allows users to write in human-readable markup.  `MyST` (Markedly Structured Text) is an extended flavor of `Markdown` which helps parse content in `Markdown` so that `Sphinx` can convert the content into a static webpage.

## Statement of Need
 Together, `Sphinx`, `MyST`, and `Markdown` help streamline webpage creation by focusing on content creation using `Markdown`, with useful built-in features (like cross-referencing and document structure) without having to tinker with the HTML or the CSS files---as long as pre-built styles are acceptable to personal tastes (`CSS` is can still be specified). Pre-built styling and themes are defined in a configuration (`conf.py`) file. This workflow should be useful if already familiar with `Markdown` (and some `Python`---config file is in `Python`). An example of a HTML that can be generated is this static HTML page itself.


## Preparing Sphinx
[`Sphinx`](https://www.sphinx-doc.org/en/master/) is designed as a documentation generator that can convert lightweight markup text files (like `reStructuredText` and `Markdown`) into HTML websites (and other formats, including `PDF`).

`Sphinx` is written in Python but is supported and can be installed across multiple platforms. 

To install from `pip` just do

```bash
$ pip install -U sphinx
```

The `-U` option installs the latest version, overriding older versions if they exist.

``````{toggle}
:show:

For installation of `Sphinx` via `chocolatey` or `brew`:
````{tab-set}
```{tab-item} winOS
$ `choco install sphinx`
```

```{tab-item} macOS
$ `brew install sphinx-doc`
```
````
``````

## Preparing MyST
[`MyST-Parser`](https://github.com/executablebooks/MyST-Parser) is a flavor of `Markdown` that acts as a [bridge](https://www.sphinx-doc.org/en/master/usage/markdown.html#markdown) between `Markdown` and `Sphinx`, which by default, works out of the box with `.rst` files.

To install the `MyST` parser from `pip`
```bash
$ pip install myst-parser
```


## Make the HTML with `Markdown`, `Sphinx`, and `MyST`

Start by initiating a document folder using `Sphinx` by typing
```bash
$ sphinx-quickstart proj-name
```
where `proj-name` is the name of the root path of the project. Follow the prompts to key in some basic information. The `proj-name/` folder will then be populated with the relevant assets, including a GNU `Makefile` with recipes to `make` the `HTML`.

```bash
$ tree
```
```{code-block} bash
:caption: Output

.
|-- Makefile
|-- _build
|-- _static
|-- _templates
|-- conf.py
|-- index.rst
`-- make.bat
```

An `index.rst` is included in `proj-name/`, and an `HTML` page can already be generated using `index.rst` by typing 
```bash
$ make html
```
But since this is about `Markdown`, the `index.rst` won't be needed. Instead, the webpage content should be in some `Markdown` file like `index.md` (in `proj-name/`).

To use the `MyST` parser so that Sphinx can convert the `index.md` into `HTML`, the `conf.py` file needs to be edited. Open `conf.py` and add the `myst-parser` `Sphinx` extension module to the `extensions` list:

```{code-block} python
:caption: conf.py

...
extensions = [
    ...
    "myst_parser",
]
...
```

The `HTML` can now be generated using the content in `index.md` by typing
```bash
$ make html
```
and the output will be in `proj-name/_build/html/`. The contents there can now be served online.


## Customizing basic settings
The `HTML` is ready, but the `conf.py` file also allows further customizations.

`Sphinx` is designed for technical documentation and automatically appends some string (e.g., — `proj-name`  documentation") to the title. This can be changed in the source `HTML` (`<title>...</title>`) or from `conf.py` by setting the `html_title" option` to empty. (The default will be the title of the `index.md` file without any suffix).

```{code-block} python
:caption: conf.py

...
html_title = ""
...
```


Certain behaviors, like the size of headers or scroll behavior, can be controlled from a `CSS` file. Calls to custom `CSS` files can be configured in `conf.py` by adding paths to `CSS` files

```{code-block} python
:caption: conf.py

...
html_css_files = [
    ...
    "../_static/custom.css",
    # can also be URLs
    "https://example.com/css/custom.css",
    ]
...
```

or adding paths that contain the custom static files (like style sheets)

```{code-block} python
:caption: conf.py

...
html_static_path = [
    ...
    "../_static/",
    ]
...
```

See the [`Sphinx configuration`](https://www.sphinx-doc.org/en/master/usage/configuration.html) docs for more configuration options.


## Theming
Swapping themes shipped with Sphinx is easy. The default theme I'm getting in `conf.py` is `alabaster`. But it can be easily changed to another theme like `classic'`

```{code-block} python
:caption: conf.py

...
html_theme = "classic"
...
```

[Other themes](https://sphinx-themes.org/) are also available. For example, to use the `yummy` theme, install it
```bash
$ pip install yummy-sphinx-theme
```
and set it `conf.py`

```{code-block} python
:caption: conf.py

...
html_theme = "yummy_sphinx_theme"
...
```

Do a `make html` again and the new theme will be reflected and the [`yummy`](https://sphinx-themes.org/sample-sites/yummy-sphinx-theme/) theme looks something like below.

**Screenshot of Yummy**
![Yummy theme](yummy.png "Yummy theme").


## HTML admonitions

To add admonitions in the `HTML` style, use a syntax that looks like that

````{code-block} markdown
:caption: index.md

...
```{admonition} My admonition title

Content
```
...
````

to get

<div class="admonition warning other">
  <p class="admonition-title">My admonition title</p>
  <p>Content</p>
</div>

and 

````{code-block} markdown
:caption: index.md

...
```{admonition} My tip
:class: tip

Tip here.
```
...
````

to get

<div class="admonition tip">
  <p class="admonition-title">My tip</p>
  <p>Tip here.</p>
</div>

In summary, this vignette covers how I made this vignette.


## Resources
* [Sphinx installation](https://www.sphinx-doc.org/en/master/usage/installation.html)
* [Sphinx with Markdown](https://www.sphinx-doc.org/en/master/usage/markdown.html#markdown)
* [MyST-Parser](https://github.com/executablebooks/MyST-Parser)
* [Sphinx configuration](https://www.sphinx-doc.org/en/master/usage/configuration.html)
* [Sphinx themes](https://sphinx-themes.org/)
* [https://github.com/executablebooks/MyST-Parser/issues/154#issuecomment-662022814](https://github.com/executablebooks/MyST-Parser/issues/154#issuecomment-662022814)
* [https://myst-parser.readthedocs.io/en/latest/syntax/admonitions.html](https://myst-parser.readthedocs.io/en/latest/syntax/admonitions.html)
