let configuration =   object (self)     method output_directory =       env "OUTPUT_DIR" |> Option.value ~default:"_doc"     method input_files =       env "INPUT" |> Option.value ~default:""       |> String.split ~on:(`Character ',')       |> List.map ~f:(fun path ->           try             if Sys.is_directory path             then all_files path             else [path]           with _ -> [])       |> List.concat     method index_file =       env "INDEX" |> Option.value ~default:"README.md"     method stylesheets =       env "CSS" |> Option.map ~f:(String.split ~on:(`Character ','))       |> Option.value ~default:default_stylesheets     method api_doc_directory =       env "API"     method title_prefix =       env "TITLE_PREFIX" |> Option.value ~default:""     method title_substitutions =       env "TITLE_SUBSTITUTIONS"       |> Option.value_map ~default:[] ~f:parse_list_of_substitutions     method title ?(with_prefix=true) t =       let tt =         List.find_map self#title_substitutions ~f:(function           | (a, b) when               a = t || (try Filename.chop_extension a = t with _ -> false->             Some b           | _ -> None)         |> function         | Some b -> b         | None ->           String.map t ~f:(function '_' -> ' ' | c -> c)       in       sprintf "%s%s" (if with_prefix then self#title_prefix else "") tt     method command_substitutions =       env "COMMAND_SUBSTITUTIONS"       |> Option.value_map ~default:[] ~f:parse_list_of_substitutions     method catch_module_paths =       env "CATCH_MODULE_PATHS"       |> Option.value_map ~default:[] ~f:parse_list_of_substitutions       |> List.filter_map ~f:(fun (pattern, prefix) ->           try Some (pattern, Re_posix.compile_pat pattern, prefix)           with _ -> None)     method add_to_menu =       env "ADD_TO_MENU"       |> Option.value ~default:""     method display =       let list_of_paths l =         (List.map l ~f:(sprintf "  - %S") |> String.concat ~sep:"\n"in       let variable_note var =         say "  (%S is %s)" var           (match env var with None -> "empty" | Some s -> sprintf "%S" s) in       say "Output directory: %s" self#output_directory;       variable_note "OUTPUT_DIR";       say "Input files:\n%s"         (list_of_paths self#input_files);       variable_note "INPUT";       say "Style sheets:\n%s" (list_of_paths self#stylesheets);       variable_note "CSS";       begin match self#api_doc_directory with       | Some s -> say "Getting API docs from: %S" s       | None -> say "No getting API docs (*Warning*)"       end;       variable_note "API";       say "Title prefix: %S" self#title_prefix;       variable_note "TITLE_PREFIX";       say "Command substitutions:";       List.iter self#command_substitutions (fun (a, b) -> say "  - %s → %s" a b);       variable_note "COMMAND_SUBSTITUTIONS";       say "Index file: %s" self#index_file;       variable_note "INDEX";       say "Catch module paths:";       List.iter self#catch_module_paths (fun (a,_, b) ->           say "  - %S → Prefix: %s" a b);       variable_note "CATCH_MODULE_PATHS";       say "Add to the menu: %S" self#add_to_menu;       variable_note "ADD_TO_MENU";       ()   end