qp2/ocaml/README_qp_edit.rst

210 lines
4.3 KiB
ReStructuredText

Adding a new block
==================
In this section, we assume we will add the `New_keyword` keyword.
Create the `Input_new_keyword.ml` file
--------------------------------------
Copy for example the `Input_full_ci.ml` file as a starting point.
The template is the following, where `r_x`, `r_y`, ..., `last_r` are the records
of the block.
.. code-block:: ocaml
module New_keyword : sig
type t =
{ r_x : Type_of_x.t
r_y : Y_type.t
...
last_r : bool
} [@@deriving sexp]
;;
val read : unit -> t
val write : t -> unit
val to_rst : t -> Rst_string.t
val of_rst : Rst_string.t -> t option
end = struct
type t =
{ r_x : Type_of_x.t
r_y : Y_type.t
...
last_r : bool
} [@@deriving sexp]
;;
let get_default = Qpackage.get_ezfio_default "new_keyword";;
...
end
The following functions need to be defined
.. code-block:: ocaml
val read : unit -> t
val write : t -> unit
val to_rst : t -> Rst_string.t
val of_rst : Rst_string.t -> t option
The type `t` has to be defined in a same way in the `sig` and the `struct`.
For each record of the type `t`, use types defined in the `Qptypes.ml` file as
much as possible.
The `get_default` function will fetch the default values in the `ezfio_defaults` file
in the `new_keyword` block.
For each record `r_x` of the type `t`, create a `read_r_x ()` function
and a `write_r_x r_x` function that performs the I/O in the EZFIO.
To set a default value in the `read_r_x` function, use the following template
(assuming that the `Type_of_x` is built from a `double precision` value in
the EZFIO file).
.. code-block:: ocaml
let read_r_x () =
if not (Ezfio.has_new_keyword_r_x ()) then
get_default "r_x"
|> Float.of_string
|> Ezfio.set_new_keyword_r_x
;
Ezfio.get_new_keyword_r_x ()
|> Type_of_x.of_float
;;
let write_r_x r_x =
Type_of_x.to_float r_x
|> Ezfio.set_new_keyword_r_x
;;
Then, create a `read` and a `write` function as
.. code-block:: ocaml
let read () =
{ r_x = read_r_x () ;
r_y = read_r_y () ;
...
last_r = read_last_r () ;
}
;;
let write { r_x ;
r_y
...
last_r ;
} =
write_r_x r_x;
write_r_y r_y;
...
write_last_r last_r;
;;
Finally, create the functions to write an RST string as
.. code-block:: ocaml
let to_rst b =
Printf.sprintf "
You can put here some documentation as long as there is no equal sign.
The record entries should be indented on the right with a blank line
before and a blank line after, as they would be in a rst file.
Here is the text for r_x
r_x = %s
And here is the text for r_y
r_y = %s
...
Finally, the text for last_r
last_r = %s
"
(Type_of_x.to_string b.r_x)
(Y_type.to_string b.r_y)
...
(Bool.to_string b.last_r)
;;
and you can use the generic `of_rst` function to read it back:
.. code-block:: ocaml
include Generic_input_of_rst;;
let of_rst = of_rst t_of_sexp;;
Add module to `Input.ml` file
-----------------------------
Append module to the `Input.ml` file. Use the name of the `Input_new_keyword.ml` without the
`.ml` suffix.
.. code-block:: ocaml
include Input_new_keyword;;
In the `qp_edit.ml` file
------------------------
vim search strings are given in brackets.
1. (`/type keyword`) : Add a new entry to the keyword type corresponding to the block to add:
.. code-block:: ocaml
type keyword =
...
| New_keyword
;;
2. (`/keyword_to_string`) : Add a new entry to the `keyword_to_string` function for the title of the block
.. code-block:: ocaml
let keyword_to_string = function
...
| New_keyword -> "My new keyword"
;;
3. (`/let get s`) : Add a new call to the to_rst function of the `Input.New_keyword` module
.. code-block:: ocaml
let get s =
let header = (make_header s)
and rst = let open Input in
match s with
...
| New_keyword ->
New_keyword.(to_rst (read ()))
...
4. (`/let set s`) : Add a new call to the of_rst function of the `Input.New_keyword` module
.. code-block:: ocaml
let open Input in
match s with
...
| New_keyword -> write New_keyword.(of_rst, write)
...
;;