@@ -5,7 +5,9 @@ module Code_block = struct
55 metadata : metadata option ;
66 delimiter : string option ;
77 content : Location .t ; (* Location of the content *)
8+ content_txt : string ; (* The content itself *)
89 code_block : Location .t ; (* Location of the enclosing code block *)
10+ output : t list ;
911 }
1012end
1113
@@ -36,7 +38,7 @@ let extract_code_block_info acc ~(location : Lexing.position) ~docstring =
3638 Fortunately the location info give us enough info to be able to extract
3739 the code from the original text, whitespace and all.
3840 *)
39- let handle_code_block : O.Loc.span -> _ -> Code_block.t =
41+ let rec handle_code_block : O.Loc.span -> _ -> Code_block.t =
4042 let convert_loc (sp : O.Loc.span ) =
4143 Location.
4244 {
@@ -46,7 +48,7 @@ let extract_code_block_info acc ~(location : Lexing.position) ~docstring =
4648 }
4749 in
4850 fun location
49- { O.Ast. meta; delimiter; content = { O.Loc. location = span ; _ } ; _ } ->
51+ { O.Ast. meta; delimiter; content = { O.Loc. location = span ; value } ; output } ->
5052 let metadata =
5153 Option. map
5254 (fun { O.Ast. language; tags } ->
@@ -57,12 +59,14 @@ let extract_code_block_info acc ~(location : Lexing.position) ~docstring =
5759 in
5860 let content = convert_loc span in
5961 let code_block = convert_loc location in
60- { metadata; delimiter; content; code_block }
61- in
62+ let output = Option. map (List. fold_left fold_fn [] )
63+ (output :> O.Ast.block_element O.Ast.with_location list option ) in
64+ let output = Option. value ~default: [] output in
65+ { metadata; delimiter; content; content_txt = value; code_block; output }
6266
6367 (* Fold over the results from odoc-parser, recurse where necessary
6468 and extract the code block metadata *)
65- let rec fold_fn acc (elt : O.Ast.block_element O.Loc.with_location ) =
69+ and fold_fn acc (elt : O.Ast.block_element O.Loc.with_location ) =
6670 match elt with
6771 | { O.Loc. value = `Code_block c ; location } ->
6872 handle_code_block location c :: acc
@@ -137,34 +141,10 @@ let slice file_contents (loc : Location.t) =
137141 Error: expected int, got string
138142 ]err}
139143 ]} *)
140- let slice_error (code_block : Code_block.t ) file_contents =
141- let starts = code_block.content.loc_end.pos_cnum in
142- let ends = code_block.code_block.loc_end.pos_cnum in
143- let len = ends - starts in
144- let str = String. sub file_contents starts len in
145- let no_errors = Fmt. str " ]%a}" Fmt. (option string ) code_block.delimiter in
146- if str = no_errors then []
147- else
148- let sep = Fmt. str " ]%a[\n " Fmt. (option string ) code_block.delimiter in
149- assert (Astring.String. is_prefix ~affix: sep str);
150- assert (Astring.String. is_suffix ~affix: " ]}" str);
151- let str =
152- String. sub str (String. length sep)
153- (String. length str - String. length sep - 2 )
154- in
155- let location =
156- { code_block.content.loc_end with pos_cnum = starts + String. length sep }
157- in
158- match extract_code_block_info [] ~location ~docstring: str with
159- | [ x ] ->
160- let lines =
161- x.content |> slice file_contents |> String. split_on_char '\n'
162- in
163- let lines =
164- (* Discard the first and last lines *)
165- List. tl (List. rev (List. tl (List. rev lines)))
166- in
167- List. map output_of_line lines
144+ let slice_error (code_block : Code_block.t ) =
145+ match code_block.output with
146+ | [] -> []
147+ | [ x ] -> x.content_txt |> output_of_line |> fun x -> [ x ]
168148 | _ -> assert false
169149
170150(* Given code block metadata and the original file, this function splices the
@@ -197,7 +177,7 @@ let make_block code_block file_contents =
197177 let contents =
198178 slice file_contents code_block.content |> String. split_on_char '\n'
199179 in
200- let errors = slice_error code_block file_contents in
180+ let errors = slice_error code_block in
201181 Block. mk ~loc: code_block.code_block ~section: None ~labels ~header
202182 ~contents ~legacy_labels: false ~errors ~delim
203183
0 commit comments