owned this note
owned this note
Published
Linked with GitHub
# Odoc 3.0 Planning: Assets and medias in odoc
This discussion builds on https://github.com/ocaml/odoc/discussions/1097, focusing on assets and media elements.
## Referencing assets
Recall from https://github.com/ocaml/odoc/discussions/1097:
> A 'unit of documentation' consists of a set of documents and assets in a hierarchical directory structure. Documentation files are mld files, and assets are jpegs, pngs, svgs, etc., that are referenced by the docs.
Assets are part of the hierarchy. They are referenced in a similar way to pages. The new `asset` keyword can be used to disambiguate. Here are some examples of reference to assets: `"data.json"`, `asset-"data.json"`, `data/"example.json"`, or `data/asset-"example.json"`.
### Asset path
When references are used in places where we know they should link to assets (see [here](#Including-media)), some of the syntax for general references is not needed, but tedious to escape. In particular, dots (`.`) and dashes (`-`) are often seen in filenames but interpreted by odoc, leading to additional `"`, as in `{!directory/"file.img"}`.
In order to make it easier to write, we define asset path as normal references where the part after the last `/` is considered verbatim. So an asset path `dirname/file-name.extension` is parsed as the normal reference `dirname/"file-name.extension"`.
### Resolving assets within a page
When resolving asset references/paths in a page within the hierarchy, assets can be resolved relatively or absolutely, up to the root of the documentation tree. For example, given the hierarchy (omitting `index.mld` files: all directories must contain an `index.mld`, even if they do not contain a page but only assets!):
```
/data.json
/a/result.dat
/a/b/baz.mld
/a/b/image.jpg
/a/b/d/windows.exe
/a/c/template.ml
```
when resolving in `baz.mld`, the following are valid paths (assuming our package name is `pkgname`):
```
{!../result.dat}
{!../c/template.ml}
{!../../data.json}
{!d/windows.exe}
{!image.jpg}
{!/pkgname/data.json}
{!/otherpackage/something_in_another_package.txt}
```
For completeness, here are the same path but written as references (instead of asset paths):
```
{!../asset-"result.dat"} or {!../"result.dat"}
{!../c/asset-"template.ml"} or {!../c/"template.ml"}
{!../../asset-"data.json"}
{!d/"windows.exe"}
{!dir-d/"windows.exe"}
{!"image.jpg"}
{!/pkgname/asset-"data.json"} or {!/pkgname/"data.json"}
{!/otherpackage/asset-something_in_another_package}
```
### Resolving assets within a module
The same mechanism that adds a package's documentation pages to the scope also adds the corresponding assets. The asset path `/packagename/a/b/c/d.txt` would refer to the asset that usually ends up installed at `<opam dir>/doc/<packagename>/odoc-pages/a/b/c/d.txt`
## Including media
The syntax for including media builds on the syntax for reference links. A media is inserted by `{<media><kind><target>}` where:
- `<media>` can be either `figure` for figures, `image` for images, `audio` for audio, and `video` for video, or `asset` for asset links
- `<sep>` is either `!` if `<target>` is an [asset path](#Asset-path), or `:` if `<target>` is a link.
`{asset:<link>}` renders the same as `{:<link>}`.
An additional "replacement", "caption" or "alternative" text can be added with the following syntax: `{{<media><kind><target>}<replacement text>}`. The replacement text can only contain inline elements.
Here is the meaning of each media:
| Media | Rendered as | Type | Text used as | Text can contain |
|----------|-------------|----------------|--------------------|-------------------------------------------|
| `asset` | link | Inline | Displayed text | Inlines but no links |
| `image` | image | Nestable block | alternative | Text |
| `video` | video | Nestable block | alternative | Inlines |
| `audio` | audio | Nestable block | alternative | Inlines |
<!-- | `figure` | figure | Nestable block | media then caption | Image, Audio or Video followed by Inlines |
The `figure` media is a little bit more complex than other medias. -->
Here are some examples:
```
{image!../figure.jpg}
{image!../figure.jpg}
{{image!ellen.jpg}Astronaut Ellen Ochoa}
{image:https://picsum.photos/200/300}
{{image:https://picsum.photos/200/300}Randomly chosen image}
{video!dirname/output.mpg}
{video!/pkgname/output.mpg}
{video:https://example.com/output.mpg}
{{video!/pkgname/output.mpg}The output from pkgname is very cool!}
{{video:https://example.com/output.mpg}Introductory video}
{audio!dirname/output.ogg}
{audio!/pkgname/output.ogg}
{audio:https://example.com/output.ogg}
{{audio!/pkgname/output.ogg}The output from pkgname is very cool!}
{{audio:https://example.com/output.ogg}Introductory video}
{asset!dirname/output.ogg}
{asset!/pkgname/output.ogg}
{{asset!/pkgname/output.ogg}The output from pkgname is very cool!}
```
## Figures
Medias can be included in (captioned) figures. This allows to reference them.
The syntax is as follows: `{figure<?:id> <media>}` or `{{figure<?:id> <media>}<caption>}` where:
- `<?:id>` is either empty or a `:` followed by an `id`. If no `id` is given, one is autogenerated from the caption (if existant).
- `<media>` is either an image, audio or video element,
- `<caption>` consists of the inline elements that will be rendered as the caption for the figure.
Figures are nestable block elements. They can be referenced by id (using the `label` prefix for disambiguation).
Examples:
```
{figure {image!kangaroo.svg}}
{figure {image!kangaroo.svg}
Kangaroo numbers in Victoria from 1880 to 1980}
Refer to {!"kangaroo-numbers-in-victoria-from-1880-to-1980"} for more details.
{figure:kang {image!kangaroo.svg}
Kangaroo numbers in Victoria from 1880 to 1980}
Refer to {!kang} for more details.
{figure:kang
{{image!kangaroo.svg}
Line graph showing a doubling of kangaroo numbers from 1880 to 1980}
Kangaroo numbers in Victoria from 1880 to 1980}
```
The last example, taken from [here](https://www.stylemanual.gov.au/content-types/images/alt-text-captions-and-titles-images), shows that alternative text and caption are different.
Audio and video are also allowed in figures:
```
{figure
{{video!flowers.mpg}Video of flower growing in rocky ground}
These beautiful flowers (Hoary sunray) decorate the Snowy Mountains in summer}
{figure
{{audio!birds.mp3}Sounds of birds}
The audio landscape in this country is very nice}
```
## Rendering medias
### HTML
Rendering media in html is easy thanks to HTML5 features.
The size for rendered images and figures depend on the size of the asset. Audio and video have controls embedded.
### Latex
How medias are inserted in latex is made on a best-effort basis. Here are some ideas:
- Links to assets could be made using [attachfile2](https://www.ctan.org/pkg/attachfile2).
- Image assets could be made using `\includegraphics`.
- Images with absolute links could be made using this [trick](https://tex.stackexchange.com/questions/5433/can-i-use-an-image-located-on-the-web-in-a-latex-document)
- Figures are made using the figure environment.
- Video and audio could be made using the [media9](https://ctan.org/pkg/media9) package.
Medias are rendered without size specification: they use the original size of the media. They are block elements.
## Assets for installed packages
Assets should be installed in the hierarchy that starts at `<pkgname>/odoc-pages/`. Additionally, any file installed in `<pkgname>/odoc-assets/` will be equivalent to the file installed in `<pkgname>/odoc-pages/_assets/`. This allows compatibility with the [`odig` convention](https://erratique.ch/software/odig/doc/packaging.html#odoc_api_and_manual).