this repo has no description
1open Odoc_utils
2
3module Path = Paths.Path
4module Reference = Paths.Reference
5module Identifier = Paths.Identifier
6
7type 'a with_location = 'a Location_.with_location
8
9type style = [ `Bold | `Italic | `Emphasis | `Superscript | `Subscript ]
10
11type alignment = [ `Left | `Center | `Right ]
12
13type media = [ `Image | `Audio | `Video ]
14
15type raw_markup_target = string
16
17type leaf_inline_element =
18 [ `Space
19 | `Word of string
20 | `Code_span of string
21 | `Math_span of string
22 | `Raw_markup of raw_markup_target * string ]
23
24type non_link_inline_element =
25 [ leaf_inline_element
26 | `Styled of style * non_link_inline_element with_location list ]
27
28(* The cross-referencer stores section heading text, and sometimes pastes it
29 into link contents. This type alias is provided for use by the
30 cross-referencer. *)
31type link_content = non_link_inline_element with_location list
32
33type reference_element = [ `Reference of Reference.t * link_content ]
34
35type inline_element =
36 [ leaf_inline_element
37 | `Styled of style * inline_element with_location list
38 | reference_element
39 | `Link of string * link_content ]
40
41type paragraph = inline_element with_location list
42
43type module_reference = {
44 module_reference : Reference.Module.t;
45 module_synopsis : paragraph option;
46}
47(** The [{!modules: ...}] markup. [module_synopsis] is initially [None], it is
48 resolved during linking. *)
49
50type 'a cell = 'a with_location list * [ `Header | `Data ]
51type 'a row = 'a cell list
52type 'a grid = 'a row list
53
54type 'a abstract_table = {
55 data : 'a grid;
56 align : alignment option list option;
57}
58
59type media_href = [ `Link of string | `Reference of Reference.Asset.t ]
60
61type media_element = [ `Media of media_href * media * string ]
62
63type code_block = {
64 meta : Odoc_parser.Ast.code_block_meta option;
65 delimiter : string option;
66 content : string with_location;
67 (** This is the raw content, that is the exact string inside the
68 delimiters. In order to get the "processed" content, see
69 {!Odoc_parser.codeblock_content} *)
70 output : nestable_block_element with_location list option;
71}
72
73and nestable_block_element =
74 [ `Paragraph of paragraph
75 | `Code_block of code_block
76 | `Math_block of string
77 | `Verbatim of string
78 | `Modules of module_reference list
79 | `Table of nestable_block_element abstract_table
80 | `List of
81 [ `Unordered | `Ordered ] * nestable_block_element with_location list list
82 | media_element ]
83
84type tag =
85 [ `Author of string
86 | `Deprecated of nestable_block_element with_location list
87 | `Param of string * nestable_block_element with_location list
88 | `Raise of
89 [ `Code_span of string | reference_element ]
90 * nestable_block_element with_location list
91 | `Return of nestable_block_element with_location list
92 | `See of
93 [ `Url | `File | `Document ]
94 * string
95 * nestable_block_element with_location list
96 | `Since of string
97 | `Before of string * nestable_block_element with_location list
98 | `Version of string
99 | `Alert of string * string option
100 | `Custom of string * nestable_block_element with_location list ]
101
102type heading_level =
103 [ `Title
104 | `Section
105 | `Subsection
106 | `Subsubsection
107 | `Paragraph
108 | `Subparagraph ]
109
110type attached_block_element = [ nestable_block_element | `Tag of tag ]
111
112type heading_attrs = {
113 heading_level : heading_level;
114 heading_label_explicit : bool;
115 (** Whether the label have been written by the user. *)
116}
117
118type block_element =
119 [ nestable_block_element
120 | `Heading of
121 heading_attrs * Identifier.Label.t * inline_element with_location list
122 | `Tag of tag ]
123
124type elements = block_element with_location list
125
126type docs = { elements : elements; warnings_tag : string option }
127
128type docs_or_stop = [ `Docs of docs | `Stop ]
129
130(** The synopsis is the first element of a comment if it is a paragraph.
131 Otherwise, there is no synopsis. *)
132let synopsis = function
133 | { Location_.value = `Paragraph p; _ } :: _ -> Some p
134 | _ -> None
135
136let rec link_content_of_inline_element :
137 inline_element with_location -> link_content =
138 fun x ->
139 let v = x.Location_.value in
140 match v with
141 | #leaf_inline_element as e -> [ { x with value = e } ]
142 | `Reference (_, r) -> r
143 | `Link (_, l) -> l
144 | `Styled (st, elems) ->
145 [ { x with value = `Styled (st, link_content_of_inline_elements elems) } ]
146
147and link_content_of_inline_elements l =
148 l |> List.map link_content_of_inline_element |> List.concat
149
150let find_zero_heading docs : link_content option =
151 List.find_map
152 (fun doc ->
153 match doc.Location_.value with
154 | `Heading ({ heading_level = `Title; _ }, _, h_content) ->
155 Some (link_content_of_inline_elements h_content)
156 | _ -> None)
157 docs
158
159(* Used in particular to sort the title names *)
160let to_string (l : link_content) =
161 let rec s_of_i (i : non_link_inline_element) =
162 match i with
163 | `Code_span s -> s
164 | `Word w -> w
165 | `Math_span m -> m
166 | `Space -> " "
167 | `Styled (_, is) -> s_of_is is
168 | `Raw_markup (_, r) -> r
169 and s_of_is is =
170 is
171 |> List.map (fun { Location_.value; _ } -> s_of_i value)
172 |> String.concat ~sep:""
173 in
174 s_of_is l