Skip to content

Media in odoc 3! #1184

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
- Added a `--asset-path` arg to `html-generate` (@panglesd, #1185)
- Add a frontmatter syntax for mld pages (@panglesd, #1187)
- Add a 'remap' option to HTML generation for partial docsets (@jonludlam, #1189)
- Added an `html-generate-asset` command (@panglesd, #1185)
- Added syntax for images, videos, audio (@panglesd, #1184)

### Changed

Expand Down
1 change: 1 addition & 0 deletions doc/ocamldoc_differences.mld
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ The following describes the changes between what [odoc] understands and what’s

{3 Improvements}
- [odoc] supports writing mathematics and tables with a specific syntax.
- [odoc] supports the inclusion of medias such as audio, video and image.
- [odoc] has a better mechanism for disambiguating references in comments. See 'reference syntax' later in this document.
- Built-in support for standalone [.mld] files. These are documents using the OCamldoc markup, but they’re rendered as distinct pages.
- Structured output: [odoc] can produce output in a structured directory tree rather a set of files.
Expand Down
31 changes: 31 additions & 0 deletions doc/odoc_for_authors.mld
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,37 @@ would render as
The light syntax has the advantages of being arguably more readable for small tables when viewing the source file directly. However, its content is restricted (for instance, no new line is allowed).
The heavy syntax is easier to write, can be more readable for big tables, and supports having any kind of content inside. It does not support alignment (yet).

{2 Medias}

Odoc 3.0 introduced new markup for medias. Medias are nestable blocks,
so they can be put inside lists and tables, but they cannot be
inlined, for instance in a link.

There are currently three kinds of medias: image, audio, and
video. Each of them can refer to the file either using an asset
reference, or a direct link.

The markup for images is [{image:<link>}], [{image!<path>}],
[{{image:<link>}Replacement text}] and [{{image!<path>}Replacement text}], where
[<link>] is a link and [<path>] is a path to an asset. This path can be either
relative or absolute.

The markup for videos and audios is similar, replacing [image] by respectively
[video] and [audio].

The replacement text is used for backends that do not support medias
(latex and man), and for when a reference is unresolved. In the case
of an image, it is also used to generate an alternative text.

Images are clickable and link to the image file.

The following source:

{[
renders as: {image:https://picsum.photos/200/300}
]}

renders as: {image:https://picsum.photos/200/300}

{2 Stop Comments}

Expand Down
47 changes: 40 additions & 7 deletions src/document/comment.ml
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ module Reference = struct
in
match Url.from_identifier ~stop_before:false id with
| Ok url ->
let target = InternalLink.Resolved url in
let link = { InternalLink.target; content; tooltip } in
[ inline @@ Inline.InternalLink link ]
let target = Target.Internal (Resolved url) in
let link = { Link.target; content; tooltip } in
[ inline @@ Inline.Link link ]
| Error (Not_linkable _) -> content
| Error exn ->
(* FIXME: better error message *)
Expand All @@ -137,9 +137,9 @@ module Reference = struct
[ inline @@ Inline.Source s ]
| Some content ->
let link =
{ InternalLink.target = Unresolved; content; tooltip = Some s }
{ Link.target = Internal Unresolved; content; tooltip = Some s }
in
[ inline @@ Inline.InternalLink link ])
[ inline @@ Inline.Link link ])
end

let leaf_inline_element : Comment.leaf_inline_element -> Inline.one = function
Expand Down Expand Up @@ -184,7 +184,7 @@ let rec inline_element : Comment.inline_element -> Inline.t = function
| [] -> [ inline @@ Text target ]
| _ -> non_link_inline_element_list content
in
[ inline @@ Link (target, content) ]
[ inline @@ Link { target = External target; content; tooltip = None } ]

and inline_element_list elements =
List.concat
Expand Down Expand Up @@ -277,6 +277,32 @@ let rec nestable_block_element :
and raise warnings *)
in
[ block @@ Table { data; align } ]
| `Media (href, media, content) ->
let content =
match (content, href) with
| "", `Reference path ->
Reference.render_unresolved (path :> Comment.Reference.t)
| "", `Link href -> href
| _ -> content
in
let url =
match href with
| `Reference (`Resolved r) -> (
let id =
Odoc_model.Paths.Reference.Resolved.Asset.(identifier (r :> t))
in
match Url.from_asset_identifier id with
| url -> Target.Internal (Resolved url))
| `Reference _ -> Internal Unresolved
| `Link href -> External href
in
let i =
match media with
| `Audio -> Block.Audio (url, content)
| `Video -> Video (url, content)
| `Image -> Image (url, content)
in
[ block i ]

and paragraph : Comment.paragraph -> Block.one = function
| [ { value = `Raw_markup (target, s); _ } ] ->
Expand Down Expand Up @@ -322,7 +348,14 @@ let tag : Comment.tag -> Description.one =
| `See (kind, target, content) ->
let value =
match kind with
| `Url -> mk_value (Inline.Link (target, [ inline @@ Text target ]))
| `Url ->
mk_value
(Inline.Link
{
target = External target;
content = [ inline @@ Text target ];
tooltip = None;
})
| `File -> mk_value (Inline.Source (source_of_code target))
| `Document -> mk_value (Inline.Text target)
in
Expand Down
13 changes: 7 additions & 6 deletions src/document/doctree.ml
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ end = struct
| Entity _ as t -> return t
| Linebreak as t -> return t
| Styled (st, content) -> return (Styled (st, remove_links content))
| Link (_, t) -> t
| InternalLink { target = Resolved _; content = t; _ } -> t
| InternalLink { target = Unresolved; content = t; _ } -> t
| Link { target = _; content = t; _ } -> t
| Source l ->
let rec f = function
| Source.Elt t -> Source.Elt (remove_links t)
Expand Down Expand Up @@ -388,7 +386,11 @@ end = struct
List.exists (List.exists (fun (cell, _) -> block cell)) data
| Description x -> description x
| Math _ -> true
| Source _ | Verbatim _ | Raw_markup _ -> false
| Audio (_, _)
| Video (_, _)
| Image (_, _)
| Source _ | Verbatim _ | Raw_markup _ ->
false
in
List.exists block_ x

Expand All @@ -400,8 +402,7 @@ end = struct
fun x ->
match x.desc with
| Styled (_, x) -> inline x
| Link (_, x) -> inline x
| InternalLink x -> inline x.content
| Link { content = t; _ } -> inline t
| Math _ -> true
| Text _ | Entity _ | Linebreak | Source _ | Raw_markup _ -> false
in
Expand Down
8 changes: 4 additions & 4 deletions src/document/generator.ml
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ let type_var tv = tag "type-var" (O.txt tv)
let enclose ~l ~r x = O.span (O.txt l ++ x ++ O.txt r)

let resolved p content =
let link = { InternalLink.target = Resolved p; content; tooltip = None } in
O.elt [ inline @@ InternalLink link ]
let link = { Link.target = Internal (Resolved p); content; tooltip = None } in
O.elt [ inline @@ Link link ]

let path p content = resolved (Url.from_path p) content

let unresolved content =
let link = { InternalLink.target = Unresolved; content; tooltip = None } in
O.elt [ inline @@ InternalLink link ]
let link = { Link.target = Internal Unresolved; content; tooltip = None } in
O.elt [ inline @@ Link link ]

let path_to_id path =
match Url.Anchor.from_identifier (path :> Paths.Identifier.t) with
Expand Down
5 changes: 2 additions & 3 deletions src/document/sidebar.ml
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,8 @@ type t = { pages : pages list; libraries : library list }
let of_lang (v : Odoc_model.Lang.Sidebar.t) =
let sidebar_toc_entry id content =
let href = id |> Url.Path.from_identifier |> Url.from_path in
let target = InternalLink.Resolved href in
let link = { InternalLink.target; content; tooltip = None } in
inline @@ Inline.InternalLink link
let target = Target.Internal (Resolved href) in
inline @@ Inline.Link { target; content; tooltip = None }
in
let pages =
let page_hierarchy { Odoc_model.Lang.Sidebar.page_name; pages } =
Expand Down
23 changes: 15 additions & 8 deletions src/document/types.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@ module rec Class : sig
end =
Class

and InternalLink : sig
type target = Resolved of Url.t | Unresolved
and Link : sig
type t = { target : Target.t; content : Inline.t; tooltip : string option }
end =
Link

and Target : sig
type internal = Resolved of Url.t | Unresolved

type href = string

type t = { target : target; content : Inline.t; tooltip : string option }
type t = Internal of internal | External of href
end =
InternalLink
Target

and Raw_markup : sig
type target = Odoc_model.Comment.raw_markup_target
Expand All @@ -36,8 +43,6 @@ end =
and Inline : sig
type entity = string

type href = string

type t = one list

and one = { attr : Class.t; desc : desc }
Expand All @@ -47,8 +52,7 @@ and Inline : sig
| Entity of entity
| Linebreak
| Styled of style * t
| Link of href * t
| InternalLink of InternalLink.t
| Link of Link.t
| Source of Source.t
| Math of Math.t
| Raw_markup of Raw_markup.t
Expand Down Expand Up @@ -90,6 +94,9 @@ and Block : sig
| Verbatim of string
| Raw_markup of Raw_markup.t
| Table of t Table.t
| Image of Target.t * string
| Video of Target.t * string
| Audio of Target.t * string

and list_type = Ordered | Unordered
end =
Expand Down
2 changes: 2 additions & 0 deletions src/document/url.ml
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,8 @@ let from_identifier ~stop_before = function
Ok (from_path @@ Path.from_identifier p)
| p -> Anchor.from_identifier p

let from_asset_identifier p = from_path @@ Path.from_identifier p

let kind id =
match Anchor.from_identifier id with
| Error e -> failwith (Error.to_string e)
Expand Down
2 changes: 2 additions & 0 deletions src/document/url.mli
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ val from_path : Path.t -> t

val from_identifier : stop_before:bool -> Identifier.t -> (t, Error.t) result

val from_asset_identifier : Identifier.AssetFile.t -> t

val kind : Identifier.t -> kind

val render_path : Odoc_model.Paths.Path.t -> string
3 changes: 1 addition & 2 deletions src/document/utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ and compute_length_inline (t : Types.Inline.t) : int =
| Text s -> acc + String.length s
| Entity _e -> acc + 1
| Linebreak -> 0 (* TODO *)
| Styled (_, t) | Link (_, t) | InternalLink { content = t; _ } ->
acc + compute_length_inline t
| Styled (_, t) | Link { content = t; _ } -> acc + compute_length_inline t
| Source s -> acc + compute_length_source s
| Math _ -> assert false
| Raw_markup _ -> assert false
Expand Down
Loading
Loading