• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ocaml / odoc / 2833

20 Feb 2025 12:27PM UTC coverage: 73.423% (+0.01%) from 73.409%
2833

push

github

jonludlam
Changelog entry for #1314

10288 of 14012 relevant lines covered (73.42%)

9931.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

42.22
/src/parser/token.ml
1
(* This module contains the token type, emitted by the lexer, and consumed by
2
   the comment syntax parser. It also contains two functions that format tokens
3
   for error messages. *)
4

5
type section_heading = [ `Begin_section_heading of int * string option ]
6
type style = [ `Bold | `Italic | `Emphasis | `Superscript | `Subscript ]
7
type paragraph_style = [ `Left | `Center | `Right ]
8

9
type tag =
10
  [ `Tag of
11
    [ `Author of string
12
    | `Deprecated
13
    | `Param of string
14
    | `Raise of string
15
    | `Return
16
    | `See of [ `Url | `File | `Document ] * string
17
    | `Since of string
18
    | `Before of string
19
    | `Version of string
20
    | `Canonical of string
21
    | `Children_order
22
    | `Toc_status
23
    | `Order_category
24
    | `Short_title
25
    | `Inline
26
    | `Open
27
    | `Closed
28
    | `Hidden ] ]
29

30
type media = [ `Audio | `Video | `Image ]
31
type media_href = [ `Reference of string | `Link of string ]
32

33
type media_markup =
34
  [ `Simple_media of media_href * media
35
  | `Media_with_replacement_text of media_href * media * string ]
36

37
let s_of_media kind media =
38
  match (kind, media) with
59✔
39
  | `Simple, `Audio -> "{audio!"
5✔
40
  | `Simple, `Video -> "{video!"
5✔
41
  | `Simple, `Image -> "{image!"
7✔
42
  | `Replaced, `Audio -> "{{audio!"
8✔
43
  | `Replaced, `Video -> "{{video!"
8✔
44
  | `Replaced, `Image -> "{{image!"
26✔
45

46
type t =
47
  [ (* End of input. *)
48
    `End
49
  | (* Runs of whitespace. [Blank_line] is any run of whitespace that contains two
50
       or more newline characters. [Single_newline] is any run of whitespace that
51
       contains exactly one newline character. [Space] is any run of whitespace
52
       that contains no newline characters.
53

54
       It is an important invariant in the parser that no adjacent whitespace
55
       tokens are emitted by the lexer. Otherwise, there would be the need for
56
       unbounded lookahead, a (co-?)ambiguity between
57
       [Single_newline Single_newline] and [Blank_line], and other problems. *)
58
    `Space of string
59
  | `Single_newline of string
60
  | `Blank_line of string
61
  | (* A right curly brace ([}]), i.e. end of markup. *)
62
    `Right_brace
63
  | `Right_code_delimiter
64
  | (* Words are anything that is not whitespace or markup. Markup symbols can be
65
       be part of words if escaped.
66

67
       Words can contain plus and minus symbols, but those are emitted as [Plus]
68
       and [Minus] tokens. The parser combines plus and minus into words, except
69
       when they appear first on a line, in which case the tokens are list item
70
       bullets. *)
71
    `Word of string
72
  | `Code_span of string
73
  | `Raw_markup of string option * string
74
  | `Math_span of string
75
  | `Math_block of string
76
  | `Begin_style of style
77
  | `Begin_paragraph_style of paragraph_style
78
  | (* Other inline element markup. *)
79
    `Simple_reference of string
80
  | `Begin_reference_with_replacement_text of string
81
  | `Simple_link of string
82
  | `Begin_link_with_replacement_text of string
83
  | media_markup
84
  | (* Leaf block element markup. *)
85
    `Code_block of
86
    (string Loc.with_location * string Loc.with_location option) option
87
    * string
88
    * string Loc.with_location
89
    * bool
90
  | `Verbatim of string
91
  | `Modules of string
92
  | (* List markup. *)
93
    `Begin_list of [ `Unordered | `Ordered ]
94
  | `Begin_list_item of [ `Li | `Dash ]
95
  | (* Table markup. *)
96
    `Begin_table_light
97
  | `Begin_table_heavy
98
  | `Begin_table_row
99
  | `Begin_table_cell of [ `Header | `Data ]
100
  | `Minus
101
  | `Plus
102
  | `Bar
103
  | section_heading
104
  | tag ]
105

106
let print : [< t ] -> string = function
107
  | `Begin_paragraph_style `Left -> "'{L'"
×
108
  | `Begin_paragraph_style `Center -> "'{C'"
×
109
  | `Begin_paragraph_style `Right -> "'{R'"
×
110
  | `Begin_style `Bold -> "'{b'"
3✔
111
  | `Begin_style `Italic -> "'{i'"
×
112
  | `Begin_style `Emphasis -> "'{e'"
×
113
  | `Begin_style `Superscript -> "'{^'"
×
114
  | `Begin_style `Subscript -> "'{_'"
×
115
  | `Begin_reference_with_replacement_text _ -> "'{{!'"
×
116
  | `Begin_link_with_replacement_text _ -> "'{{:'"
×
117
  | `Begin_list_item `Li -> "'{li ...}'"
10✔
118
  | `Begin_list_item `Dash -> "'{- ...}'"
5✔
119
  | `Begin_table_light -> "{t"
×
120
  | `Begin_table_heavy -> "{table"
×
121
  | `Begin_table_row -> "'{tr'"
×
122
  | `Begin_table_cell `Header -> "'{th'"
×
123
  | `Begin_table_cell `Data -> "'{td'"
×
124
  | `Minus -> "'-'"
2✔
125
  | `Plus -> "'+'"
2✔
126
  | `Bar -> "'|'"
×
127
  | `Begin_section_heading (level, label) ->
4✔
128
      let label = match label with None -> "" | Some label -> ":" ^ label in
×
129
      Printf.sprintf "'{%i%s'" level label
130
  | `Tag (`Author _) -> "'@author'"
5✔
131
  | `Tag `Deprecated -> "'@deprecated'"
2✔
132
  | `Tag (`Param _) -> "'@param'"
1✔
133
  | `Tag (`Raise _) -> "'@raise'"
×
134
  | `Tag `Return -> "'@return'"
×
135
  | `Tag `Children_order -> "'@children_order'"
×
136
  | `Tag `Order_category -> "'@order_category'"
×
137
  | `Tag `Toc_status -> "'@toc_status'"
×
138
  | `Tag `Short_title -> "'@short_title'"
×
139
  | `Tag (`See _) -> "'@see'"
×
140
  | `Tag (`Since _) -> "'@since'"
×
141
  | `Tag (`Before _) -> "'@before'"
×
142
  | `Tag (`Version _) -> "'@version'"
×
143
  | `Tag (`Canonical _) -> "'@canonical'"
×
144
  | `Tag `Inline -> "'@inline'"
×
145
  | `Tag `Open -> "'@open'"
×
146
  | `Tag `Closed -> "'@closed'"
×
147
  | `Tag `Hidden -> "'@hidden"
×
148
  | `Raw_markup (None, _) -> "'{%...%}'"
×
149
  | `Raw_markup (Some target, _) -> "'{%" ^ target ^ ":...%}'"
×
150
  | `Simple_media (`Reference _, `Image) -> "{image!...}"
×
151
  | `Simple_media (`Reference _, `Audio) -> "{audio!...}"
×
152
  | `Simple_media (`Reference _, `Video) -> "{video!...}"
×
153
  | `Simple_media (`Link _, `Image) -> "{image:...}"
×
154
  | `Simple_media (`Link _, `Audio) -> "{audio:...}"
×
155
  | `Simple_media (`Link _, `Video) -> "{video:...}"
×
156
  | `Media_with_replacement_text (`Reference _, `Image, _) ->
×
157
      "{{image!...} ...}"
158
  | `Media_with_replacement_text (`Reference _, `Audio, _) ->
×
159
      "{{audio!...} ...}"
160
  | `Media_with_replacement_text (`Reference _, `Video, _) ->
×
161
      "{{video!...} ...}"
162
  | `Media_with_replacement_text (`Link _, `Image, _) -> "{{image:...} ...}"
×
163
  | `Media_with_replacement_text (`Link _, `Audio, _) -> "{{audio:...} ...}"
×
164
  | `Media_with_replacement_text (`Link _, `Video, _) -> "{{video:...} ...}"
×
165

166
(* [`Minus] and [`Plus] are interpreted as if they start list items. Therefore,
167
   for error messages based on [Token.describe] to be accurate, formatted
168
   [`Minus] and [`Plus] should always be plausibly list item bullets. *)
169
let describe : [< t | `Comment ] -> string = function
170
  | `Word w -> Printf.sprintf "'%s'" w
10✔
171
  | `Code_span _ -> "'[...]' (code)"
5✔
172
  | `Raw_markup _ -> "'{%...%}' (raw markup)"
3✔
173
  | `Begin_paragraph_style `Left -> "'{L ...}' (left alignment)"
1✔
174
  | `Begin_paragraph_style `Center -> "'{C ...}' (center alignment)"
1✔
175
  | `Begin_paragraph_style `Right -> "'{R ...}' (right alignment)"
1✔
176
  | `Begin_style `Bold -> "'{b ...}' (boldface text)"
16✔
177
  | `Begin_style `Italic -> "'{i ...}' (italic text)"
×
178
  | `Begin_style `Emphasis -> "'{e ...}' (emphasized text)"
×
179
  | `Begin_style `Superscript -> "'{^...}' (superscript)"
2✔
180
  | `Begin_style `Subscript -> "'{_...}' (subscript)"
×
181
  | `Math_span _ -> "'{m ...}' (math span)"
×
182
  | `Math_block _ -> "'{math ...}' (math block)"
×
183
  | `Simple_reference _ -> "'{!...}' (cross-reference)"
×
184
  | `Begin_reference_with_replacement_text _ ->
6✔
185
      "'{{!...} ...}' (cross-reference)"
186
  | `Simple_media (`Reference _, `Image) -> "'{image!...}' (image-reference)"
×
187
  | `Simple_media (`Reference _, `Audio) -> "'{audio!...}' (audio-reference)"
×
188
  | `Simple_media (`Reference _, `Video) -> "'{video!...}' (video-reference)"
×
189
  | `Simple_media (`Link _, `Image) -> "'{image:...}' (image-link)"
×
190
  | `Simple_media (`Link _, `Audio) -> "'{audio:...}' (audio-link)"
×
191
  | `Simple_media (`Link _, `Video) -> "'{video:...}' (video-link)"
×
192
  | `Media_with_replacement_text (`Reference _, `Image, _) ->
14✔
193
      "'{{image!...} ...}' (image-reference)"
194
  | `Media_with_replacement_text (`Reference _, `Audio, _) ->
3✔
195
      "'{{audio!...} ...}' (audio-reference)"
196
  | `Media_with_replacement_text (`Reference _, `Video, _) ->
3✔
197
      "'{{video!...} ...}' (video-reference)"
198
  | `Media_with_replacement_text (`Link _, `Image, _) ->
2✔
199
      "'{{image:...} ...}' (image-link)"
200
  | `Media_with_replacement_text (`Link _, `Audio, _) ->
2✔
201
      "'{{audio:...} ...}' (audio-link)"
202
  | `Media_with_replacement_text (`Link _, `Video, _) ->
2✔
203
      "'{{video:...} ...}' (video-link)"
204
  | `Simple_link _ -> "'{:...} (external link)'"
2✔
205
  | `Begin_link_with_replacement_text _ -> "'{{:...} ...}' (external link)"
3✔
206
  | `End -> "end of text"
21✔
207
  | `Space _ -> "whitespace"
×
208
  | `Single_newline _ -> "line break"
1✔
209
  | `Blank_line _ -> "blank line"
6✔
210
  | `Right_brace -> "'}'"
×
211
  | `Right_code_delimiter -> "']}'"
4✔
212
  | `Code_block _ -> "'{[...]}' (code block)"
11✔
213
  | `Verbatim _ -> "'{v ... v}' (verbatim text)"
13✔
214
  | `Modules _ -> "'{!modules ...}'"
5✔
215
  | `Begin_list `Unordered -> "'{ul ...}' (bulleted list)"
27✔
216
  | `Begin_list `Ordered -> "'{ol ...}' (numbered list)"
×
217
  | `Begin_list_item `Li -> "'{li ...}' (list item)"
13✔
218
  | `Begin_list_item `Dash -> "'{- ...}' (list item)"
3✔
219
  | `Begin_table_light -> "'{t ...}' (table)"
3✔
220
  | `Begin_table_heavy -> "'{table ...}' (table)"
2✔
221
  | `Begin_table_row -> "'{tr ...}' (table row)"
2✔
222
  | `Begin_table_cell `Header -> "'{th ... }' (table header cell)"
×
223
  | `Begin_table_cell `Data -> "'{td ... }' (table data cell)"
×
224
  | `Minus -> "'-' (bulleted list item)"
18✔
225
  | `Plus -> "'+' (numbered list item)"
2✔
226
  | `Bar -> "'|'"
×
227
  | `Begin_section_heading (level, _) ->
18✔
228
      Printf.sprintf "'{%i ...}' (section heading)" level
229
  | `Tag (`Author _) -> "'@author'"
18✔
230
  | `Tag `Deprecated -> "'@deprecated'"
5✔
231
  | `Tag (`Param _) -> "'@param'"
3✔
232
  | `Tag (`Raise _) -> "'@raise'"
×
233
  | `Tag `Return -> "'@return'"
×
234
  | `Tag (`See _) -> "'@see'"
1✔
235
  | `Tag (`Since _) -> "'@since'"
2✔
236
  | `Tag (`Before _) -> "'@before'"
×
237
  | `Tag (`Version _) -> "'@version'"
2✔
238
  | `Tag (`Canonical _) -> "'@canonical'"
2✔
239
  | `Tag `Inline -> "'@inline'"
×
240
  | `Tag `Open -> "'@open'"
×
241
  | `Tag `Closed -> "'@closed'"
×
242
  | `Tag `Hidden -> "'@hidden"
×
243
  | `Tag `Children_order -> "'@children_order"
×
244
  | `Tag `Toc_status -> "'@toc_status"
×
245
  | `Tag `Order_category -> "'@order_category"
×
246
  | `Tag `Short_title -> "'@short_title"
×
247
  | `Comment -> "top-level text"
4✔
248

249
let describe_element = function
250
  | `Reference (`Simple, _, _) -> describe (`Simple_reference "")
×
251
  | `Reference (`With_text, _, _) ->
×
252
      describe (`Begin_reference_with_replacement_text "")
253
  | `Link _ -> describe (`Begin_link_with_replacement_text "")
×
254
  | `Heading (level, _, _) -> describe (`Begin_section_heading (level, None))
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc