Skip to content

Commit 46b4c45

Browse files
gpetiotjonludlam
authored andcommitted
Add syntax for tables
1 parent ebfd3b9 commit 46b4c45

File tree

9 files changed

+992
-1
lines changed

9 files changed

+992
-1
lines changed

src/ast.ml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
type 'a with_location = 'a Loc.with_location
1111
type style = [ `Bold | `Italic | `Emphasis | `Superscript | `Subscript ]
12+
type alignment = [ `Left | `Center | `Right ]
1213

1314
type reference_kind = [ `Simple | `With_text ]
1415
(** References in doc comments can be of two kinds: [{!simple}] or [{{!ref}With text}]. *)
@@ -29,6 +30,11 @@ type inline_element =
2930
text. Similarly the [`Link] constructor has the link itself as first parameter
3031
and the second is the replacement text. *)
3132

33+
type 'a cell = 'a with_location list
34+
type 'a row = 'a cell list
35+
type 'a grid = 'a row list
36+
type 'a abstract_table = 'a row * 'a grid * alignment option list
37+
3238
type nestable_block_element =
3339
[ `Paragraph of inline_element with_location list
3440
| `Code_block of
@@ -41,13 +47,18 @@ type nestable_block_element =
4147
[ `Unordered | `Ordered ]
4248
* [ `Light | `Heavy ]
4349
* nestable_block_element with_location list list
50+
| `Table of table
4451
| `Math_block of string (** @since 2.0.0 *) ]
4552
(** Some block elements may be nested within lists or tags, but not all.
4653
The [`List] constructor has a parameter of type [\[`Light | `Heavy\]].
4754
This corresponds to the syntactic constructor used (see the
4855
{{:https://ocaml.org/releases/4.12/htmlman/ocamldoc.html#sss:ocamldoc-list}manual}).
4956
*)
5057

58+
and table =
59+
[ `Light of inline_element abstract_table
60+
| `Heavy of nestable_block_element abstract_table ]
61+
5162
type internal_tag =
5263
[ `Canonical of string with_location | `Inline | `Open | `Closed ]
5364
(** Internal tags are used to exercise fine control over the output of odoc. They

src/compat.ml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module Option = struct
2+
type 'a t = 'a option = None | Some of 'a
3+
4+
let is_some = function None -> false | Some _ -> true
5+
6+
let value_exn = function
7+
| None -> failwith "Option.value_exn None"
8+
| Some x -> x
9+
10+
let join_list l =
11+
if List.for_all is_some l then Some (List.map value_exn l) else None
12+
end
13+
14+
module Char = struct
15+
include Char
16+
17+
let equal (x : char) y = x = y
18+
end
19+
20+
module String = struct
21+
include String
22+
23+
let for_all f str =
24+
let rec aux i =
25+
if i >= String.length str then true
26+
else if f (String.get str i) then aux (i + 1)
27+
else false
28+
in
29+
aux 0
30+
end

src/compat.mli

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
(** @since 4.08 *)
2+
module Option : sig
3+
type 'a t = 'a option = None | Some of 'a
4+
5+
val is_some : 'a option -> bool
6+
(** [is_some o] is [true] if and only if [o] is [Some o]. *)
7+
8+
val join_list : 'a option list -> 'a list option
9+
end
10+
11+
module Char : sig
12+
include module type of Char
13+
14+
val equal : t -> t -> bool
15+
(** The equal function for chars.
16+
@since 4.03.0 *)
17+
end
18+
19+
module String : sig
20+
include module type of String
21+
22+
val for_all : (char -> bool) -> string -> bool
23+
(** [for_all p s] checks if all characters in [s] satisfy the preficate [p].
24+
@since 4.13.0 *)
25+
end

src/lexer.mll

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ let heading_level input level =
244244

245245

246246
let markup_char =
247-
['{' '}' '[' ']' '@']
247+
['{' '}' '[' ']' '@' '|']
248248
let space_char =
249249
[' ' '\t' '\n' '\r']
250250
let bullet_char =
@@ -289,6 +289,9 @@ rule token input = parse
289289
| (horizontal_space* (newline horizontal_space*)? as p) '}'
290290
{ emit input `Right_brace ~adjust_start_by:p }
291291

292+
| '|'
293+
{ emit input `Bar }
294+
292295
| word_char (word_char | bullet_char | '@')*
293296
| bullet_char (word_char | bullet_char | '@')+ as w
294297
{ emit input (`Word (unescape_word w)) }
@@ -398,6 +401,21 @@ rule token input = parse
398401
| "{-"
399402
{ emit input (`Begin_list_item `Dash) }
400403

404+
| "{table"
405+
{ emit input (`Begin_table `Heavy) }
406+
407+
| "{t"
408+
{ emit input (`Begin_table `Light) }
409+
410+
| "{tr"
411+
{ emit input `Begin_table_row }
412+
413+
| "{th"
414+
{ emit input `Begin_table_header }
415+
416+
| "{td"
417+
{ emit input `Begin_table_data }
418+
401419
| '{' (['0'-'9']+ as level) ':' (([^ '}'] # space_char)* as label)
402420
{ emit
403421
input (`Begin_section_heading (heading_level input level, Some label)) }

0 commit comments

Comments
 (0)