diff --git a/dev/iter/Iter/IO/index.html b/dev/iter/Iter/IO/index.html index fcb0452..fccea19 100644 --- a/dev/iter/Iter/IO/index.html +++ b/dev/iter/Iter/IO/index.html @@ -1,5 +1,5 @@ -
Iter.IO
Basic IO
Very basic interface to manipulate files as iterator of chunks/lines. The iterators take care of opening and closing files properly; every time one iterates over an iterator, the file is opened/closed again.
Example: copy a file "a"
into file "b"
, removing blank lines:
Iterator.(IO.lines_of "a" |> filter (fun l-> l<> "") |> IO.write_lines "b");;
By chunks of 4096
bytes:
Iterator.IO.(chunks_of ~size:4096 "a" |> write_to "b");;
Read the lines of a file into a list:
Iterator.IO.lines "a" |> Iterator.to_list
val lines_of : ?mode:int -> ?flags:Stdlib.open_flag list -> string -> string t
lines_of filename
reads all lines of the given file. It raises the same exception as would opening the file and read from it, except from End_of_file
(which is caught). The file is always properly closed. Every time the iterator is iterated on, the file is opened again, so different iterations might return different results
val chunks_of :
+IO (iter.Iter.IO) Module Iter.IO
Basic IO
Very basic interface to manipulate files as iterator of chunks/lines. The iterators take care of opening and closing files properly; every time one iterates over an iterator, the file is opened/closed again.
Example: copy a file "a"
into file "b"
, removing blank lines:
Iterator.(IO.lines_of "a" |> filter (fun l-> l<> "") |> IO.write_lines "b");;
By chunks of 4096
bytes:
Iterator.IO.(chunks_of ~size:4096 "a" |> write_to "b");;
Read the lines of a file into a list:
Iterator.IO.lines "a" |> Iterator.to_list
val lines_of : ?mode:int -> ?flags:Stdlib.open_flag list -> string -> string t
lines_of filename
reads all lines of the given file. It raises the same exception as would opening the file and read from it, except from End_of_file
(which is caught). The file is always properly closed. Every time the iterator is iterated on, the file is opened again, so different iterations might return different results
val chunks_of :
?mode:int ->
?flags:Stdlib.open_flag list ->
?size:int ->
diff --git a/dev/iter/Iter/Infix/index.html b/dev/iter/Iter/Infix/index.html
index cf11faf..6a6e0cf 100644
--- a/dev/iter/Iter/Infix/index.html
+++ b/dev/iter/Iter/Infix/index.html
@@ -1,2 +1,2 @@
-Infix (iter.Iter.Infix) Module Iter.Infix
val (--) : int -> int -> int t
a -- b
is the range of integers from a
to b
, both included, in increasing order. It will therefore be empty if a > b
.
val (--^) : int -> int -> int t
a --^ b
is the range of integers from b
to a
, both included, in decreasing order (starts from a
). It will therefore be empty if a < b
.
+Infix (iter.Iter.Infix) Module Iter.Infix
val (--) : int -> int -> int t
a -- b
is the range of integers from a
to b
, both included, in increasing order. It will therefore be empty if a > b
.
val (--^) : int -> int -> int t
a --^ b
is the range of integers from b
to a
, both included, in decreasing order (starts from a
). It will therefore be empty if a < b
.
diff --git a/dev/iter/Iter/Map/Adapt/index.html b/dev/iter/Iter/Map/Adapt/index.html
index c7800fe..be42282 100644
--- a/dev/iter/Iter/Map/Adapt/index.html
+++ b/dev/iter/Iter/Map/Adapt/index.html
@@ -1,5 +1,5 @@
-Adapt (iter.Iter.Map.Adapt) Module Map.Adapt
Adapt a pre-existing Map module to make it iterator-aware
Parameters
Signature
include Stdlib.Map.S with type key = M.key with type 'a t = 'a M.t
val empty : 'a t
val is_empty : 'a t -> bool
val merge :
+Adapt (iter.Iter.Map.Adapt) Module Map.Adapt
Adapt a pre-existing Map module to make it iterator-aware
Parameters
Signature
include Stdlib.Map.S with type key = M.key with type 'a t = 'a M.t
val empty : 'a t
val is_empty : 'a t -> bool
val merge :
(key -> 'a option -> 'b option -> 'c option) ->
'a t ->
'b t ->
diff --git a/dev/iter/Iter/Map/Make/index.html b/dev/iter/Iter/Map/Make/index.html
index 2d5ac4c..d1c6e87 100644
--- a/dev/iter/Iter/Map/Make/index.html
+++ b/dev/iter/Iter/Map/Make/index.html
@@ -1,5 +1,5 @@
-Make (iter.Iter.Map.Make) Module Map.Make
Create an enriched Map module, with iterator-aware functions
Parameters
Signature
include Stdlib.Map.S with type key = V.t
val empty : 'a t
val is_empty : 'a t -> bool
val merge :
+Make (iter.Iter.Map.Make) Module Map.Make
Create an enriched Map module, with iterator-aware functions
Parameters
Signature
include Stdlib.Map.S with type key = V.t
val empty : 'a t
val is_empty : 'a t -> bool
val merge :
(key -> 'a option -> 'b option -> 'c option) ->
'a t ->
'b t ->
diff --git a/dev/iter/Iter/Map/index.html b/dev/iter/Iter/Map/index.html
index e7b2ac0..0b82e94 100644
--- a/dev/iter/Iter/Map/index.html
+++ b/dev/iter/Iter/Map/index.html
@@ -1,4 +1,4 @@
-Map (iter.Iter.Map) Module Iter.Map
module type S = sig ... end
module Adapt
+Map (iter.Iter.Map) Module Iter.Map
module type S = sig ... end
Adapt a pre-existing Map module to make it iterator-aware
diff --git a/dev/iter/Iter/Map/module-type-S/index.html b/dev/iter/Iter/Map/module-type-S/index.html
index 5ba14e3..fdb90b5 100644
--- a/dev/iter/Iter/Map/module-type-S/index.html
+++ b/dev/iter/Iter/Map/module-type-S/index.html
@@ -1,5 +1,5 @@
-S (iter.Iter.Map.S) Module type Map.S
include Stdlib.Map.S
val empty : 'a t
val is_empty : 'a t -> bool
val merge :
+S (iter.Iter.Map.S) Module type Map.S
include Stdlib.Map.S
val empty : 'a t
val is_empty : 'a t -> bool
val merge :
(key -> 'a option -> 'b option -> 'c option) ->
'a t ->
'b t ->
diff --git a/dev/iter/Iter/Set/Adapt/index.html b/dev/iter/Iter/Set/Adapt/index.html
index 87b2366..bbe29d6 100644
--- a/dev/iter/Iter/Set/Adapt/index.html
+++ b/dev/iter/Iter/Set/Adapt/index.html
@@ -1,2 +1,2 @@
-Adapt (iter.Iter.Set.Adapt) Module Set.Adapt
Create an enriched Set module from the given one
Parameters
Signature
+Adapt (iter.Iter.Set.Adapt) Module Set.Adapt
Create an enriched Set module from the given one
Parameters
Signature
diff --git a/dev/iter/Iter/Set/Make/index.html b/dev/iter/Iter/Set/Make/index.html
index 1cef559..070f7a2 100644
--- a/dev/iter/Iter/Set/Make/index.html
+++ b/dev/iter/Iter/Set/Make/index.html
@@ -1,2 +1,2 @@
-Make (iter.Iter.Set.Make) Module Set.Make
Functor to build an extended Set module from an ordered type
Parameters
Signature
+Make (iter.Iter.Set.Make) Module Set.Make
Functor to build an extended Set module from an ordered type
Parameters
Signature
diff --git a/dev/iter/Iter/Set/index.html b/dev/iter/Iter/Set/index.html
index 45a9a22..35420ea 100644
--- a/dev/iter/Iter/Set/index.html
+++ b/dev/iter/Iter/Set/index.html
@@ -1,2 +1,2 @@
-Set (iter.Iter.Set) Module Iter.Set
module type S = sig ... end
Create an enriched Set module from the given one
+Set (iter.Iter.Set) Module Iter.Set
module type S = sig ... end
Create an enriched Set module from the given one
diff --git a/dev/iter/Iter/Set/module-type-S/index.html b/dev/iter/Iter/Set/module-type-S/index.html
index 68a95cd..f8670e1 100644
--- a/dev/iter/Iter/Set/module-type-S/index.html
+++ b/dev/iter/Iter/Set/module-type-S/index.html
@@ -1,2 +1,2 @@
-S (iter.Iter.Set.S) Module type Set.S
+S (iter.Iter.Set.S) Module type Set.S
diff --git a/dev/iter/Iter/index.html b/dev/iter/Iter/index.html
index 957f0d9..d19db1a 100644
--- a/dev/iter/Iter/index.html
+++ b/dev/iter/Iter/index.html
@@ -1,5 +1,5 @@
-Iter (iter.Iter) Module Iter
Simple and Efficient Iterators.
The iterators are designed to allow easy transfer (mappings) between data structures, without defining n^2
conversions between the n
types. The implementation relies on the assumption that an iterator can be iterated on as many times as needed; this choice allows for high performance of many combinators. However, for transient iterators, the persistent
function is provided, storing elements of a transient iterator in memory; the iterator can then be used several times (See further).
Note that some combinators also return iterators (e.g. group
). The transformation is computed on the fly every time one iterates over the resulting iterator. If a transformation performs heavy computation, persistent
can also be used as intermediate storage.
Most functions are lazy, i.e. they do not actually use their arguments until their result is iterated on. For instance, if one calls map
on an iterator, one gets a new iterator, but nothing else happens until this new iterator is used (by folding or iterating on it).
If an iterator is built from an iteration function that is repeatable (i.e. calling it several times always iterates on the same set of elements, for instance List.iter or Map.iter), then the resulting t
object is also repeatable. For one-time iter functions such as iteration on a file descriptor or a Seq
, the persistent
function can be used to iterate and store elements in a memory structure; the result is an iterator that iterates on the elements of this memory structure, cheaply and repeatably.
An iterator of values of type 'a
. If you give it a function 'a -> unit
it will be applied to every element of the iterator successively.
type +'a iter = 'a t
Creation
val from_iter : (('a -> unit) -> unit) -> 'a t
Build an iterator from a iter function
val from_labelled_iter : (f:('a -> unit) -> unit) -> 'a t
Build an iterator from a labelled iter function
val from_fun : (unit -> 'a option) -> 'a t
Call the function repeatedly until it returns None. This iterator is transient, use persistent
if needed!
val empty : 'a t
Empty iterator. It contains no element.
val singleton : 'a -> 'a t
Singleton iterator, with exactly one element.
val doubleton : 'a -> 'a -> 'a t
Iterator with exactly two elements
val init : (int -> 'a) -> 'a t
init f
is the infinite iterator f 0; f 1; f 2; …
.
cons x l
yields x
, then yields from l
. Same as append (singleton x) l
.
Caution: it is advised not to build long iterators out of cons
, because it's inefficient. Each additional cons x i
adds one layer of function call per item traversed in i
.
val repeat : 'a -> 'a t
Infinite iterator of the same element. You may want to look at take
and the likes if you iterate on it.
val iterate : ('a -> 'a) -> 'a -> 'a t
iterate f x
is the infinite iterator x, f(x), f(f(x)), ...
val forever : (unit -> 'b) -> 'b t
Iterator that calls the given function to produce elements. The iterator may be transient (depending on the function), and definitely is infinite. You may want to use take
and persistent
.
Cycle forever through the given iterator. Assume the given iterator can be traversed any amount of times (not transient). This yields an infinite iterator, you should use something like take
not to loop forever.
val unfoldr : ('b -> ('a * 'b) option) -> 'b -> 'a t
unfoldr f b
will apply f
to b
. If it yields Some (x,b')
then x
is returned and unfoldr recurses with b'
.
Consumption
val iter : ('a -> unit) -> 'a t -> unit
Consume the iterator, passing all its arguments to the function. Basically iter f seq
is just seq f
.
val iteri : (int -> 'a -> unit) -> 'a t -> unit
Iterate on elements and their index in the iterator
val for_each : 'a t -> ('a -> unit) -> unit
Consume the iterator, passing all its arguments to the function. for_each seq f
is the same as iter f seq
, i.e., iter
with arguments reversed.
val for_eachi : 'a t -> (int -> 'a -> unit) -> unit
Iterate on elements and their index in the iterator. for_eachi seq f
is the same as iteri f seq
, i.e., iteri
with arguments reversed.
val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
Fold over elements of the iterator, consuming it
val foldi : ('a -> int -> 'b -> 'a) -> 'a -> 'b t -> 'a
Fold over elements of the iterator and their index, consuming it
fold_filter_map f acc l
is a fold_map
-like function, but the function can choose to skip an element by retuning None
.
Map objects two by two. lazily. The last element is kept in the iterator if the count is odd.
val for_all : ('a -> bool) -> 'a t -> bool
Do all elements satisfy the predicate?
val exists : ('a -> bool) -> 'a t -> bool
Exists there some element satisfying the predicate?
val mem : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> bool
Is the value a member of the iterator?
val find : ('a -> 'b option) -> 'a t -> 'b option
Find the first element on which the function doesn't return None
val find_pred : ('a -> bool) -> 'a t -> 'a option
find_pred p l
finds the first element of l
that satisfies p
, or returns None
if no element satisfies p
val length : 'a t -> int
How long is the iterator? Forces the iterator.
val is_empty : 'a t -> bool
Is the iterator empty? Forces the iterator.
Transformation
Append two iterators. Iterating on the result is like iterating on the first, then on the second.
Append iterators. Iterating on the result is like iterating on the each iterator of the list in order.
Monadic bind. Intuitively, it applies the function to every element of the initial iterator, and calls concat
. Formerly flatMap
seq_list l
returns all the ways to pick one element in each sub-iterator in l
. Assumes the sub-iterators can be iterated on several times.
seq_list_map f l
maps f
over every element of l
, then calls seq_list
Map with indices, and only keep non-None
elements
val filter_count : ('a -> bool) -> 'a t -> int
Count how many elements satisfy the given predicate
filter_some l
retains only elements of the form Some x
. Same as filter_map (fun x->x)
keep_error l
retains only elements of the form Error x
.
Caching
Iterate on the iterator, storing elements in an efficient internal structure.. The resulting iterator can be iterated on as many times as needed. Note: calling persistent on an already persistent iterator will still make a new copy of the iterator!
Lazy version of persistent
. When calling persistent_lazy s
, a new iterator s'
is immediately returned (without actually consuming s
) in constant time; the first time s'
is iterated on, it also consumes s
and caches its content into a inner data structure that will back s'
for future iterations.
warning: on the first traversal of s'
, if the traversal is interrupted prematurely (take
, etc.) then s'
will not be memorized, and the next call to s'
will traverse s
again.
Misc
Sort the iterator. Eager, O(n) ram and O(n ln(n)) time. It iterates on elements of the argument iterator immediately, before it sorts them.
Sort the iterator and remove duplicates. Eager, same as sort
val sorted : ?cmp:('a -> 'a -> int) -> 'a t -> bool
Checks whether the iterator is sorted. Eager, same as sort
.
Group equal consecutive elements. Linear time. Formerly synonym to group
. note: Order of items in each list is unspecified.
Group equal elements, disregarding their order of appearance. precondition: for any x
and y
, if eq x y
then hash x=hash y
must hold. note: Order of items in each list is unspecified.
Map each distinct element to its number of occurrences in the whole seq. Similar to group_by seq |> map (fun l->List.hd l, List.length l)
precondition: for any x
and y
, if eq x y
then hash x=hash y
must hold.
Remove consecutive duplicate elements. Basically this is like fun seq -> map List.hd (group seq)
.
Cartesian product of iterators. When calling product a b
, the caller MUST ensure that b
can be traversed as many times as required (several times), possibly by calling persistent
on it beforehand.
val diagonal_l : 'a list -> ('a * 'a) t
All pairs of distinct positions of the list. diagonal l
will return the iterator of all List.nth i l, List.nth j l
if i < j
.
All pairs of distinct positions of the iterator. Iterates only once on the iterator, which must be finite.
join ~join_row a b
combines every element of a
with every element of b
using join_row
. If join_row
returns None, then the two elements do not combine. Assume that b
allows for multiple iterations.
val join_by :
+Iter (iter.Iter) Module Iter
Simple and Efficient Iterators.
The iterators are designed to allow easy transfer (mappings) between data structures, without defining n^2
conversions between the n
types. The implementation relies on the assumption that an iterator can be iterated on as many times as needed; this choice allows for high performance of many combinators. However, for transient iterators, the persistent
function is provided, storing elements of a transient iterator in memory; the iterator can then be used several times (See further).
Note that some combinators also return iterators (e.g. group
). The transformation is computed on the fly every time one iterates over the resulting iterator. If a transformation performs heavy computation, persistent
can also be used as intermediate storage.
Most functions are lazy, i.e. they do not actually use their arguments until their result is iterated on. For instance, if one calls map
on an iterator, one gets a new iterator, but nothing else happens until this new iterator is used (by folding or iterating on it).
If an iterator is built from an iteration function that is repeatable (i.e. calling it several times always iterates on the same set of elements, for instance List.iter or Map.iter), then the resulting t
object is also repeatable. For one-time iter functions such as iteration on a file descriptor or a Seq
, the persistent
function can be used to iterate and store elements in a memory structure; the result is an iterator that iterates on the elements of this memory structure, cheaply and repeatably.
An iterator of values of type 'a
. If you give it a function 'a -> unit
it will be applied to every element of the iterator successively.
type +'a iter = 'a t
Creation
val from_iter : (('a -> unit) -> unit) -> 'a t
Build an iterator from a iter function
val from_labelled_iter : (f:('a -> unit) -> unit) -> 'a t
Build an iterator from a labelled iter function
val from_fun : (unit -> 'a option) -> 'a t
Call the function repeatedly until it returns None. This iterator is transient, use persistent
if needed!
val empty : 'a t
Empty iterator. It contains no element.
val singleton : 'a -> 'a t
Singleton iterator, with exactly one element.
val doubleton : 'a -> 'a -> 'a t
Iterator with exactly two elements
val init : (int -> 'a) -> 'a t
init f
is the infinite iterator f 0; f 1; f 2; …
.
cons x l
yields x
, then yields from l
. Same as append (singleton x) l
.
Caution: it is advised not to build long iterators out of cons
, because it's inefficient. Each additional cons x i
adds one layer of function call per item traversed in i
.
val repeat : 'a -> 'a t
Infinite iterator of the same element. You may want to look at take
and the likes if you iterate on it.
val iterate : ('a -> 'a) -> 'a -> 'a t
iterate f x
is the infinite iterator x, f(x), f(f(x)), ...
val forever : (unit -> 'b) -> 'b t
Iterator that calls the given function to produce elements. The iterator may be transient (depending on the function), and definitely is infinite. You may want to use take
and persistent
.
Cycle forever through the given iterator. Assume the given iterator can be traversed any amount of times (not transient). This yields an infinite iterator, you should use something like take
not to loop forever.
val unfoldr : ('b -> ('a * 'b) option) -> 'b -> 'a t
unfoldr f b
will apply f
to b
. If it yields Some (x,b')
then x
is returned and unfoldr recurses with b'
.
Consumption
val iter : ('a -> unit) -> 'a t -> unit
Consume the iterator, passing all its arguments to the function. Basically iter f seq
is just seq f
.
val iteri : (int -> 'a -> unit) -> 'a t -> unit
Iterate on elements and their index in the iterator
val for_each : 'a t -> ('a -> unit) -> unit
Consume the iterator, passing all its arguments to the function. for_each seq f
is the same as iter f seq
, i.e., iter
with arguments reversed.
val for_eachi : 'a t -> (int -> 'a -> unit) -> unit
Iterate on elements and their index in the iterator. for_eachi seq f
is the same as iteri f seq
, i.e., iteri
with arguments reversed.
val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
Fold over elements of the iterator, consuming it
val foldi : ('a -> int -> 'b -> 'a) -> 'a -> 'b t -> 'a
Fold over elements of the iterator and their index, consuming it
fold_filter_map f acc l
is a fold_map
-like function, but the function can choose to skip an element by retuning None
.
Map objects two by two. lazily. The last element is kept in the iterator if the count is odd.
val for_all : ('a -> bool) -> 'a t -> bool
Do all elements satisfy the predicate?
val exists : ('a -> bool) -> 'a t -> bool
Exists there some element satisfying the predicate?
val mem : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> bool
Is the value a member of the iterator?
val find : ('a -> 'b option) -> 'a t -> 'b option
Find the first element on which the function doesn't return None
val find_pred : ('a -> bool) -> 'a t -> 'a option
find_pred p l
finds the first element of l
that satisfies p
, or returns None
if no element satisfies p
val length : 'a t -> int
How long is the iterator? Forces the iterator.
val is_empty : 'a t -> bool
Is the iterator empty? Forces the iterator.
Transformation
Append two iterators. Iterating on the result is like iterating on the first, then on the second.
Append iterators. Iterating on the result is like iterating on the each iterator of the list in order.
Monadic bind. Intuitively, it applies the function to every element of the initial iterator, and calls concat
. Formerly flatMap
seq_list l
returns all the ways to pick one element in each sub-iterator in l
. Assumes the sub-iterators can be iterated on several times.
seq_list_map f l
maps f
over every element of l
, then calls seq_list
Map with indices, and only keep non-None
elements
val filter_count : ('a -> bool) -> 'a t -> int
Count how many elements satisfy the given predicate
filter_some l
retains only elements of the form Some x
. Same as filter_map (fun x->x)
keep_error l
retains only elements of the form Error x
.
Caching
Iterate on the iterator, storing elements in an efficient internal structure.. The resulting iterator can be iterated on as many times as needed. Note: calling persistent on an already persistent iterator will still make a new copy of the iterator!
Lazy version of persistent
. When calling persistent_lazy s
, a new iterator s'
is immediately returned (without actually consuming s
) in constant time; the first time s'
is iterated on, it also consumes s
and caches its content into a inner data structure that will back s'
for future iterations.
warning: on the first traversal of s'
, if the traversal is interrupted prematurely (take
, etc.) then s'
will not be memorized, and the next call to s'
will traverse s
again.
Misc
Sort the iterator. Eager, O(n) ram and O(n ln(n)) time. It iterates on elements of the argument iterator immediately, before it sorts them.
Sort the iterator and remove duplicates. Eager, same as sort
val sorted : ?cmp:('a -> 'a -> int) -> 'a t -> bool
Checks whether the iterator is sorted. Eager, same as sort
.
Group equal consecutive elements. Linear time. Formerly synonym to group
. note: Order of items in each list is unspecified.
Group equal elements, disregarding their order of appearance. precondition: for any x
and y
, if eq x y
then hash x=hash y
must hold. note: Order of items in each list is unspecified.
Map each distinct element to its number of occurrences in the whole seq. Similar to group_by seq |> map (fun l->List.hd l, List.length l)
precondition: for any x
and y
, if eq x y
then hash x=hash y
must hold.
Remove consecutive duplicate elements. Basically this is like fun seq -> map List.hd (group seq)
.
Cartesian product of iterators. When calling product a b
, the caller MUST ensure that b
can be traversed as many times as required (several times), possibly by calling persistent
on it beforehand.
val diagonal_l : 'a list -> ('a * 'a) t
All pairs of distinct positions of the list. diagonal l
will return the iterator of all List.nth i l, List.nth j l
if i < j
.
All pairs of distinct positions of the iterator. Iterates only once on the iterator, which must be finite.
join ~join_row a b
combines every element of a
with every element of b
using join_row
. If join_row
returns None, then the two elements do not combine. Assume that b
allows for multiple iterations.
val join_by :
?eq:'key equal ->
?hash:'key hash ->
('a -> 'key) ->
diff --git a/dev/iter/IterBigarray/index.html b/dev/iter/IterBigarray/index.html
index f437095..36d7a83 100644
--- a/dev/iter/IterBigarray/index.html
+++ b/dev/iter/IterBigarray/index.html
@@ -1,2 +1,2 @@
-IterBigarray (iter.IterBigarray) Module IterBigarray
Interface and Helpers for bigarrays
val of_bigarray : ('a, _, _) Stdlib.Bigarray.Array1.t -> 'a Iter.t
Iterate on the elements of a 1-D array
val mmap : string -> char Iter.t
Map the file into memory, and read the characters.
+IterBigarray (iter.IterBigarray) Module IterBigarray
Interface and Helpers for bigarrays
val of_bigarray : ('a, _, _) Stdlib.Bigarray.Array1.t -> 'a Iter.t
Iterate on the elements of a 1-D array
val mmap : string -> char Iter.t
Map the file into memory, and read the characters.
diff --git a/dev/iter/IterLabels/IO/index.html b/dev/iter/IterLabels/IO/index.html
index d628dde..fced0bd 100644
--- a/dev/iter/IterLabels/IO/index.html
+++ b/dev/iter/IterLabels/IO/index.html
@@ -1,5 +1,5 @@
-IO (iter.IterLabels.IO) Module IterLabels.IO
val lines_of : ?mode:int -> ?flags:Stdlib.open_flag list -> string -> string t
lines_of filename
reads all lines of the given file. It raises the same exception as would opening the file and read from it, except from End_of_file
(which is caught). The file is always properly closed. Every time the iterator is iterated on, the file is opened again, so different iterations might return different results
val chunks_of :
+IO (iter.IterLabels.IO) Module IterLabels.IO
val lines_of : ?mode:int -> ?flags:Stdlib.open_flag list -> string -> string t
lines_of filename
reads all lines of the given file. It raises the same exception as would opening the file and read from it, except from End_of_file
(which is caught). The file is always properly closed. Every time the iterator is iterated on, the file is opened again, so different iterations might return different results
val chunks_of :
?mode:int ->
?flags:Stdlib.open_flag list ->
?size:int ->
diff --git a/dev/iter/IterLabels/Infix/index.html b/dev/iter/IterLabels/Infix/index.html
index 53f99b1..6042623 100644
--- a/dev/iter/IterLabels/Infix/index.html
+++ b/dev/iter/IterLabels/Infix/index.html
@@ -1,2 +1,2 @@
-Infix (iter.IterLabels.Infix) Module IterLabels.Infix
val (--) : int -> int -> int t
a -- b
is the range of integers from a
to b
, both included, in increasing order. It will therefore be empty if a > b
.
val (--^) : int -> int -> int t
a --^ b
is the range of integers from b
to a
, both included, in decreasing order (starts from a
). It will therefore be empty if a < b
.
+Infix (iter.IterLabels.Infix) Module IterLabels.Infix
val (--) : int -> int -> int t
a -- b
is the range of integers from a
to b
, both included, in increasing order. It will therefore be empty if a > b
.
val (--^) : int -> int -> int t
a --^ b
is the range of integers from b
to a
, both included, in decreasing order (starts from a
). It will therefore be empty if a < b
.
diff --git a/dev/iter/IterLabels/Map/Adapt/index.html b/dev/iter/IterLabels/Map/Adapt/index.html
index bcc5705..1157667 100644
--- a/dev/iter/IterLabels/Map/Adapt/index.html
+++ b/dev/iter/IterLabels/Map/Adapt/index.html
@@ -1,5 +1,5 @@
-Adapt (iter.IterLabels.Map.Adapt) Module Map.Adapt
Adapt a pre-existing Map module to make it iterator-aware
Parameters
Signature
include Stdlib.Map.S with type key = M.key with type 'a t = 'a M.t
val empty : 'a t
val is_empty : 'a t -> bool
val merge :
+Adapt (iter.IterLabels.Map.Adapt) Module Map.Adapt
Adapt a pre-existing Map module to make it iterator-aware
Parameters
Signature
include Stdlib.Map.S with type key = M.key with type 'a t = 'a M.t
val empty : 'a t
val is_empty : 'a t -> bool
val merge :
(key -> 'a option -> 'b option -> 'c option) ->
'a t ->
'b t ->
diff --git a/dev/iter/IterLabels/Map/Make/index.html b/dev/iter/IterLabels/Map/Make/index.html
index ec75f75..bcd262b 100644
--- a/dev/iter/IterLabels/Map/Make/index.html
+++ b/dev/iter/IterLabels/Map/Make/index.html
@@ -1,5 +1,5 @@
-Make (iter.IterLabels.Map.Make) Module Map.Make
Create an enriched Map module, with iterator-aware functions
Parameters
Signature
include Stdlib.Map.S with type key = V.t
val empty : 'a t
val is_empty : 'a t -> bool
val merge :
+Make (iter.IterLabels.Map.Make) Module Map.Make
Create an enriched Map module, with iterator-aware functions
Parameters
Signature
include Stdlib.Map.S with type key = V.t
val empty : 'a t
val is_empty : 'a t -> bool
val merge :
(key -> 'a option -> 'b option -> 'c option) ->
'a t ->
'b t ->
diff --git a/dev/iter/IterLabels/Map/index.html b/dev/iter/IterLabels/Map/index.html
index fdc5d8b..f9ae537 100644
--- a/dev/iter/IterLabels/Map/index.html
+++ b/dev/iter/IterLabels/Map/index.html
@@ -1,4 +1,4 @@
-Map (iter.IterLabels.Map) Module IterLabels.Map
module type S = sig ... end
module Adapt
+Map (iter.IterLabels.Map) Module IterLabels.Map
module type S = sig ... end
Adapt a pre-existing Map module to make it iterator-aware
diff --git a/dev/iter/IterLabels/Map/module-type-S/index.html b/dev/iter/IterLabels/Map/module-type-S/index.html
index 598b49a..d78fb2e 100644
--- a/dev/iter/IterLabels/Map/module-type-S/index.html
+++ b/dev/iter/IterLabels/Map/module-type-S/index.html
@@ -1,5 +1,5 @@
-S (iter.IterLabels.Map.S) Module type Map.S
include Stdlib.Map.S
val empty : 'a t
val is_empty : 'a t -> bool
val merge :
+S (iter.IterLabels.Map.S) Module type Map.S
include Stdlib.Map.S
val empty : 'a t
val is_empty : 'a t -> bool
val merge :
(key -> 'a option -> 'b option -> 'c option) ->
'a t ->
'b t ->
diff --git a/dev/iter/IterLabels/Set/Adapt/index.html b/dev/iter/IterLabels/Set/Adapt/index.html
index af93c6b..b228a32 100644
--- a/dev/iter/IterLabels/Set/Adapt/index.html
+++ b/dev/iter/IterLabels/Set/Adapt/index.html
@@ -1,2 +1,2 @@
-Adapt (iter.IterLabels.Set.Adapt) Module Set.Adapt
Create an enriched Set module from the given one
Parameters
Signature
+Adapt (iter.IterLabels.Set.Adapt) Module Set.Adapt
Create an enriched Set module from the given one
Parameters
Signature
diff --git a/dev/iter/IterLabels/Set/Make/index.html b/dev/iter/IterLabels/Set/Make/index.html
index 9feb7c5..fb6366a 100644
--- a/dev/iter/IterLabels/Set/Make/index.html
+++ b/dev/iter/IterLabels/Set/Make/index.html
@@ -1,2 +1,2 @@
-Make (iter.IterLabels.Set.Make) Module Set.Make
Functor to build an extended Set module from an ordered type
Parameters
Signature
+Make (iter.IterLabels.Set.Make) Module Set.Make
Functor to build an extended Set module from an ordered type
Parameters
Signature
diff --git a/dev/iter/IterLabels/Set/index.html b/dev/iter/IterLabels/Set/index.html
index 4d04f49..63f9fe8 100644
--- a/dev/iter/IterLabels/Set/index.html
+++ b/dev/iter/IterLabels/Set/index.html
@@ -1,2 +1,2 @@
-Set (iter.IterLabels.Set) Module IterLabels.Set
module type S = sig ... end
Create an enriched Set module from the given one
+Set (iter.IterLabels.Set) Module IterLabels.Set
module type S = sig ... end
Create an enriched Set module from the given one
diff --git a/dev/iter/IterLabels/Set/module-type-S/index.html b/dev/iter/IterLabels/Set/module-type-S/index.html
index 43a3991..b744132 100644
--- a/dev/iter/IterLabels/Set/module-type-S/index.html
+++ b/dev/iter/IterLabels/Set/module-type-S/index.html
@@ -1,2 +1,2 @@
-S (iter.IterLabels.Set.S) Module type Set.S
+S (iter.IterLabels.Set.S) Module type Set.S
diff --git a/dev/iter/IterLabels/index.html b/dev/iter/IterLabels/index.html
index 3f41513..111d897 100644
--- a/dev/iter/IterLabels/index.html
+++ b/dev/iter/IterLabels/index.html
@@ -1,5 +1,5 @@
-IterLabels (iter.IterLabels) Module IterLabels
Simple and Efficient Iterators
Version of Iterator
with labels
An iterator of values of type 'a
. If you give it a function 'a -> unit
it will be applied to every element of the iterator successively.
type +'a iter = 'a t
NOTE Type ('a, 'b) t2 = ('a -> 'b -> unit) -> unit
has been removed and subsumed by ('a * 'b) t
Creation
val from_iter : (('a -> unit) -> unit) -> 'a t
Build an iterator from a iter function
val from_labelled_iter : (f:('a -> unit) -> unit) -> 'a t
Build an iterator from a labelled iter function
val from_fun : (unit -> 'a option) -> 'a t
Call the function repeatedly until it returns None. This iterator is transient, use persistent
if needed!
val empty : 'a t
Empty iterator. It contains no element.
val singleton : 'a -> 'a t
Singleton iterator, with exactly one element.
val doubleton : 'a -> 'a -> 'a t
Iterator with exactly two elements
val init : f:(int -> 'a) -> 'a t
init f
is the infinite iterator f 0; f 1; f 2; …
.
val repeat : 'a -> 'a t
Infinite iterator of the same element. You may want to look at take
and the likes if you iterate on it.
val iterate : ('a -> 'a) -> 'a -> 'a t
iterate f x
is the infinite iterator x, f(x), f(f(x)), ...
val forever : (unit -> 'b) -> 'b t
Iterator that calls the given function to produce elements. The iterator may be transient (depending on the function), and definitely is infinite. You may want to use take
and persistent
.
Cycle forever through the given iterator. Assume the given iterator can be traversed any amount of times (not transient). This yields an infinite iterator, you should use something like take
not to loop forever.
Consumption
val iter : f:('a -> unit) -> 'a t -> unit
Consume the iterator, passing all its arguments to the function. Basically iter f seq
is just seq f
.
val iteri : f:(int -> 'a -> unit) -> 'a t -> unit
Iterate on elements and their index in the iterator
val for_each : seq:'a t -> ('a -> unit) -> unit
Consume the iterator, passing all its arguments to the function. for_each seq f
is the same as iter f seq
, i.e., iter
with arguments reversed.
val for_eachi : seq:'a t -> (int -> 'a -> unit) -> unit
Iterate on elements and their index in the iterator. for_eachi seq f
is the same as iteri f seq
, i.e., iteri
with arguments reversed.
val fold : f:('a -> 'b -> 'a) -> init:'a -> 'b t -> 'a
Fold over elements of the iterator, consuming it
val foldi : f:('a -> int -> 'b -> 'a) -> init:'a -> 'b t -> 'a
Fold over elements of the iterator and their index, consuming it
val fold_filter_map :
+IterLabels (iter.IterLabels) Module IterLabels
Simple and Efficient Iterators
Version of Iterator
with labels
An iterator of values of type 'a
. If you give it a function 'a -> unit
it will be applied to every element of the iterator successively.
type +'a iter = 'a t
NOTE Type ('a, 'b) t2 = ('a -> 'b -> unit) -> unit
has been removed and subsumed by ('a * 'b) t
Creation
val from_iter : (('a -> unit) -> unit) -> 'a t
Build an iterator from a iter function
val from_labelled_iter : (f:('a -> unit) -> unit) -> 'a t
Build an iterator from a labelled iter function
val from_fun : (unit -> 'a option) -> 'a t
Call the function repeatedly until it returns None. This iterator is transient, use persistent
if needed!
val empty : 'a t
Empty iterator. It contains no element.
val singleton : 'a -> 'a t
Singleton iterator, with exactly one element.
val doubleton : 'a -> 'a -> 'a t
Iterator with exactly two elements
val init : f:(int -> 'a) -> 'a t
init f
is the infinite iterator f 0; f 1; f 2; …
.
val repeat : 'a -> 'a t
Infinite iterator of the same element. You may want to look at take
and the likes if you iterate on it.
val iterate : ('a -> 'a) -> 'a -> 'a t
iterate f x
is the infinite iterator x, f(x), f(f(x)), ...
val forever : (unit -> 'b) -> 'b t
Iterator that calls the given function to produce elements. The iterator may be transient (depending on the function), and definitely is infinite. You may want to use take
and persistent
.
Cycle forever through the given iterator. Assume the given iterator can be traversed any amount of times (not transient). This yields an infinite iterator, you should use something like take
not to loop forever.
Consumption
val iter : f:('a -> unit) -> 'a t -> unit
Consume the iterator, passing all its arguments to the function. Basically iter f seq
is just seq f
.
val iteri : f:(int -> 'a -> unit) -> 'a t -> unit
Iterate on elements and their index in the iterator
val for_each : seq:'a t -> ('a -> unit) -> unit
Consume the iterator, passing all its arguments to the function. for_each seq f
is the same as iter f seq
, i.e., iter
with arguments reversed.
val for_eachi : seq:'a t -> (int -> 'a -> unit) -> unit
Iterate on elements and their index in the iterator. for_eachi seq f
is the same as iteri f seq
, i.e., iteri
with arguments reversed.
val fold : f:('a -> 'b -> 'a) -> init:'a -> 'b t -> 'a
Fold over elements of the iterator, consuming it
val foldi : f:('a -> int -> 'b -> 'a) -> init:'a -> 'b t -> 'a
Fold over elements of the iterator and their index, consuming it
val fold_filter_map :
f:('acc -> 'a -> 'acc * 'b option) ->
init:'acc ->
'a t ->
diff --git a/dev/iter/index.html b/dev/iter/index.html
index f308ce0..3c3d150 100644
--- a/dev/iter/index.html
+++ b/dev/iter/index.html
@@ -1,2 +1,2 @@
-index (iter.index) iter index
Library iter
This library exposes the following toplevel modules:
Iter
Simple and Efficient Iterators.IterLabels
Library iter.bigarray
The entry point of this library is the module: IterBigarray
.
+index (iter.index) iter index
Library iter
This library exposes the following toplevel modules:
Iter
Simple and Efficient Iterators.IterLabels
Library iter.bigarray
The entry point of this library is the module: IterBigarray
.
diff --git a/dev/odoc.support/odoc.css b/dev/odoc.support/odoc.css
index 7230f82..83ebcf0 100644
--- a/dev/odoc.support/odoc.css
+++ b/dev/odoc.support/odoc.css
@@ -1,7 +1,7 @@
@charset "UTF-8";
/* Copyright (c) 2016 The odoc contributors. All rights reserved.
Distributed under the ISC license, see terms at the end of the file.
- odoc 2.3.0 */
+ odoc 2.4.0 */
/* Fonts */
/* noticia-text-regular - latin */
@@ -95,7 +95,10 @@
:root,
.light:root {
- --main-background: #FFFFFF;
+
+ scroll-padding-top: calc(var(--search-bar-height) + var(--search-padding-top) + 1em);
+
+ --main-background: #FFFFFF;
--color: #333333;
--link-color: #2C94BD;
@@ -116,6 +119,7 @@
--toc-color: #1F2D3D;
--toc-before-color: #777;
--toc-background: #f6f8fa;
+ --toc-background-emph: #ecf0f5;
--toc-list-border: #ccc;
--spec-summary-border-color: #5c9cf5;
@@ -124,6 +128,12 @@
--spec-summary-hover-background: #ebeff2;
--spec-details-after-background: rgba(0, 4, 15, 0.05);
--spec-details-after-shadow: rgba(204, 204, 204, 0.53);
+
+ --search-results-border: #bbb;
+ --search-results-shadow: #bbb;
+
+ --search-snake: #82aaff;
+
}
.dark:root {
@@ -151,6 +161,7 @@
--li-code-color: #999;
--toc-color: #777;
--toc-background: #252525;
+ --toc-background-emph: #2a2a2a;
--hljs-link: #999;
--hljs-keyword: #cda869;
@@ -161,6 +172,10 @@
--hljs-variable: #cf6a4c;
--spec-label-color: lightgreen;
+
+ --search-results-border: #505050;
+ --search-results-shadow: #404040;
+
}
@media (prefers-color-scheme: dark) {
@@ -195,6 +210,7 @@
--toc-color: #777;
--toc-before-color: #777;
--toc-background: #252525;
+ --toc-background-emph: #2a2a2a;
--toc-list-border: #ccc;
--spec-summary-hover-background: #ebeff2;
--spec-details-after-background: rgba(0, 4, 15, 0.05);
@@ -209,6 +225,10 @@
--hljs-variable: #cf6a4c;
--spec-label-color: lightgreen;
+
+ --search-results-border: #505050;
+ --search-results-shadow: #404040;
+
}
}
@@ -246,26 +266,50 @@ body {
}
body {
- margin-left: calc(10vw + 20ex);
- margin-right: 4ex;
- margin-top: 20px;
- margin-bottom: 50px;
+ margin-left: auto;
+ margin-right: auto;
+ padding: 0 4ex;
}
body.odoc {
- max-width: 100ex;
+ max-width: 132ex;
+ display: grid;
+ grid-template-columns: min-content 1fr;
+ column-gap: 4ex;
+ row-gap: 2ex;
}
body.odoc-src {
margin-right: calc(10vw + 20ex);
}
+.odoc-content {
+ grid-row: 4;
+ grid-column: 2;
+}
+
+.odoc-preamble > *:first-child {
+ /* This make the first thing in the preamble align with the sidebar */
+ padding-top: 0;
+ margin-top: 0;
+}
+
header {
margin-bottom: 30px;
}
+header.odoc-preamble {
+ grid-column: 2;
+ grid-row: 3;
+}
+
nav {
- font-family: "Fira Sans", Helvetica, Arial, sans-serif;
+ font-family: "Fira Sans", sans-serif;
+}
+
+nav.odoc-nav {
+ grid-column: 2;
+ grid-row: 2;
}
/* Basic markup elements */
@@ -396,7 +440,7 @@ a.anchor {
a.source_link {
float: right;
color: var(--source-color);
- font-family: "Fira Sans", Helvetica, Arial, sans-serif;
+ font-family: "Fira Sans", sans-serif;
font-size: initial;
}
@@ -405,13 +449,17 @@ a.source_link {
we restart the sequence there like h2 */
h1, h2, h3, h4, h5, h6, .h7, .h8, .h9, .h10 {
- font-family: "Fira Sans", Helvetica, Arial, sans-serif;
+ font-family: "Fira Sans", sans-serif;
font-weight: 400;
padding-top: 0.1em;
line-height: 1.2;
overflow-wrap: break-word;
}
+.odoc-preamble h1 {
+ margin-top: 10px;
+}
+
h1 {
font-weight: 500;
font-size: 2.441em;
@@ -459,7 +507,7 @@ h4 {
font-size: 1.12em;
}
-/* Comment delimiters, hidden but accessible to screen readers and
+/* Comment delimiters, hidden but accessible to screen readers and
selected for copy/pasting */
/* Taken from bootstrap */
@@ -479,7 +527,7 @@ h4 {
/* Preformatted and code */
tt, code, pre {
- font-family: "Fira Mono", courier;
+ font-family: "Fira Mono", monospace;
font-weight: 400;
}
@@ -549,10 +597,10 @@ div.odoc-spec,.odoc-include {
.spec.type .variant, .spec.type .record {
margin-left: 2ch;
+}
+
+.spec.type li.variant, .spec.type li.record {
list-style: none;
- display: flex;
- flex-wrap: wrap;
- row-gap: 4px;
}
.spec.type .record > code, .spec.type .variant > code {
@@ -569,9 +617,8 @@ div.odoc-spec,.odoc-include {
padding: 0.25em 0.5em;
margin-left: 10%;
border-radius: 3px;
- flex-grow:1;
background: var(--main-background);
- box-shadow: 2px 2px 4px lightgrey;
+ box-shadow: 1px 1px 2px lightgrey;
}
div.def {
@@ -739,19 +786,32 @@ td.def-doc *:first-child {
line-height: 1.2;
}
+/* When a search bar is present, we need the sticky sidebar to be a bit lower,
+ so `top` is higher */
+
+.odoc-search + * + .odoc-toc {
+ --toc-top: calc(var(--search-bar-height) + var(--search-padding-top) + 20px);
+ max-height: calc(100vh - 2 * var(--toc-top));
+ top: var(--toc-top)
+}
+
.odoc-toc {
- position: fixed;
- top: 0px;
- bottom: 0px;
- left: 0px;
- max-width: 30ex;
- min-width: 26ex;
- width: 20%;
+ --toc-top: 20px;
+ width: 28ex;
background: var(--toc-background);
overflow: auto;
color: var(--toc-color);
padding-left: 2ex;
padding-right: 2ex;
+ grid-row-start: 3;
+ grid-row-end: 5;
+ grid-column: 1;
+ height: fit-content;
+ border: solid 1px var(--border);
+ border-radius: 5px;
+ position:sticky;
+ max-height: calc(100vh - 2 * var(--toc-top));
+ top: var(--toc-top)
}
.odoc-toc ul li a {
@@ -759,15 +819,287 @@ td.def-doc *:first-child {
font-size: 0.95em;
color: var(--color);
font-weight: 400;
- line-height: 1.6em;
+ line-height: 1.2em;
display: block;
}
-.odoc-toc ul li a:hover {
+.odoc-sidebar ul li a:hover {
box-shadow: none;
text-decoration: underline;
}
+:root {
+ --search-bar-height: 25px;
+ --search-padding-top: 1rem;
+}
+
+.odoc-search {
+ position: sticky;
+ top: 0;
+ background: var(--main-background);
+ /* This amounts to fit-content when the search is not active, but when you
+ have the search results displayed, you do not want the height of the search
+ container to change. */
+ height: calc(var(--search-bar-height) + var(--search-padding-top));
+ width: 100%;
+ padding-top: var(--search-padding-top);
+ z-index: 1;
+ grid-row: 1;
+ grid-column-start: 1;
+ grid-column-end: 3;
+}
+
+
+.odoc-search .search-inner {
+ width: 100%;
+ position: relative;
+ left: 0;
+ display: grid;
+ /* The second column is for the search snake, which has 0 width */
+ grid-template-columns: 1fr 0fr;
+ grid-row-gap: 1rem;
+ /* The second row is for the search results. It has a width, but only */
+ grid-template-rows: min-content 0px;
+ background: transparent;
+}
+
+.odoc-search .search-bar {
+ position: relative;
+ z-index: 2;
+ font-size: 1em;
+ transition: font-size 0.3s;
+ box-shadow: 0px 0px 0.2rem 0.3em var(--main-background);
+ height: var(--search-bar-height);
+}
+
+.odoc-search:focus-within .search-bar {
+ font-size: 1.1em;
+}
+
+.odoc-search:not(:focus-within) .search-result {
+ display: none;
+}
+
+.odoc-search .search-result:empty {
+ display: none;
+}
+
+.odoc-search .search-result {
+ grid-row: 2;
+ background: var(--toc-background);
+ position: absolute;
+ left: 0;
+ right: 0;
+ border: solid;
+ border-color: var(--search-results-border);
+ border-width: 1px;
+ border-radius: 6px;
+ box-shadow: 0 3px 10px 2px var(--search-results-shadow), 0 0 3px 4px var(--main-background), 0px -1rem 0px 0px var(--main-background);
+ /* Works better on smallish screens with this */
+ max-height: calc(min(40rem, 50vh));
+ overflow-y: auto;
+}
+
+.search-bar {
+ /* inputs are of fixed size by default, even if you display:block them */
+ width: 100%;
+}
+
+
+.odoc-search .search-no-result {
+ color: var(--color);
+ border-bottom: var(--search-results-border) solid 1px;
+ background-color: inherit;
+ outline: 0;
+ padding: 10px;
+ padding-right: 0.5rem;
+}
+
+.search-bar-container {
+ display: flex;
+ align-items: stretch;
+ border-bottom: 1rem solid var(--main-background);
+}
+
+.search-snake {
+ grid-row: 1;
+ grid-column: 2;
+ display: flex;
+ align-items: center;
+ width: 0;
+ z-index: 2;
+ position: relative;
+ left: 0;
+ margin-top: 4px;
+ margin-bottom: 4px;
+ /* Otherwise the search snake flickers for very fast searches. */
+ transition: opacity 0.2s;
+ opacity: 0;
+}
+
+.search-snake.search-busy {
+ opacity: 1;
+}
+
+.search-snake:before {
+ content: " ";
+ display: block;
+ aspect-ratio: 1 / 1;
+ height: 100%;
+ margin-right: 4px;
+ border-radius: 50%;
+ border: 3px solid #aaa;
+ border-color: var(--search-snake) transparent var(--search-snake) transparent;
+ animation: search-snake 1.2s linear infinite;
+ position: absolute;
+ right: 0;
+}
+
+@keyframes search-snake {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+:root {
+ --kind-font-size-factor: 0.8;
+}
+
+.odoc-search .search-entry {
+ color: var(--color);
+ display: grid;
+ /* Possible kinds are the following :
+ "doc" "type" "mod" "exn" "class" "meth" "cons" "sig" "cons" "field" "val"
+ and "ext".
+ As the longest is 5 characters (and the font monospace), we give 5
+ character size to the column. However the font used for kind is a little
+ smaller, so we adjust by this factor.
+ */
+ grid-template-columns: [kinds] calc(var(--kind-font-size-factor) * 5ch) [titles] 1fr;
+ column-gap: 0.5rem;
+ border-bottom: var(--search-results-border) solid 1px;
+ background-color: inherit;
+ outline: 0;
+ padding: 0.4rem 0.4rem 0.7rem 0.7rem;
+}
+.odoc-search .search-entry p {
+ margin: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.odoc-search .search-entry:focus-visible {
+ box-shadow: none;
+ background-color: var(--target-background);
+}
+
+.odoc-search .search-entry:hover {
+ box-shadow: none;
+ background-color: var(--toc-background-emph);
+}
+
+.odoc-search .search-entry .entry-kind {
+ grid-row: 1/2;
+ grid-column: 1/2;
+ line-height: 1.4rem;
+ font-size: calc(var(--kind-font-size-factor) * 1em);
+ font-weight: bold;
+ text-align: right;
+ position: relative;
+ bottom: 0;
+}
+
+.odoc-search .search-entry pre {
+ border: none;
+ margin: 0;
+}
+
+.odoc-search .search-entry pre code {
+ font-size: 1em;
+ background-color: var(--li-code-background);
+ color: var(--li-code-color);
+ border-radius: 3px;
+ padding: 0 0.3ex;
+}
+
+.odoc-search .search-entry .entry-title {
+ width: 100%;
+ display: block;
+ grid-column: 2/2;
+ grid-row: 1/2;
+ align-self: end;
+ line-height: 1.4rem;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.odoc-search .entry-name {
+ font-weight: bold;
+}
+
+.odoc-search .prefix-name {
+ font-weight: bold;
+}
+
+.odoc-search .search-entry .prefix-name {
+ opacity: 0.7;
+}
+
+.odoc-search .entry-rhs {
+ white-space: nowrap;
+}
+
+.odoc-search .search-entry .entry-content {
+ flex-grow: 1;
+ flex-shrink: 1;
+ min-width: 0;
+}
+
+.odoc-search .search-entry .entry-comment {
+ max-height: 1.5em;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ font-size: 0.95em;
+ grid-row: 2/2;
+ grid-column: 2/2;
+}
+
+.odoc-search .search-entry .entry-comment ul {
+ white-space: nowrap;
+ display: inline;
+}
+
+.odoc-search .search-entry .entry-comment li {
+ display: inline;
+ white-space: nowrap;
+}
+
+.odoc-search .search-entry .entry-comment ul>li::before {
+ content: '•';
+}
+
+.odoc-search .search-entry .entry-comment div {
+ display: inline;
+ white-space: nowrap;
+}
+
+.odoc-search .search-entry .entry-comment p {
+ display: inline;
+ white-space: nowrap;
+}
+
+.odoc-search .search-entry .entry-comment code {
+ display: inline;
+ white-space: nowrap;
+}
+
/* First level titles */
.odoc-toc>ul>li>a {
@@ -776,6 +1108,7 @@ td.def-doc *:first-child {
.odoc-toc li ul {
margin: 0px;
+ padding-top: 0.25em;
}
.odoc-toc ul {
@@ -783,8 +1116,9 @@ td.def-doc *:first-child {
}
.odoc-toc ul li {
- margin: 0;
+ padding: 0.25em 0;
}
+
.odoc-toc>ul>li {
margin-bottom: 0.3em;
}
@@ -801,7 +1135,8 @@ td.def-doc *:first-child {
margin: 1em;
}
-.odoc-table td, .odoc-table th {
+.odoc-table td,
+.odoc-table th {
padding-left: 0.5em;
padding-right: 0.5em;
border: 1px solid black;
@@ -816,7 +1151,13 @@ td.def-doc *:first-child {
@media only screen and (max-width: 110ex) {
body {
margin: 2em;
+ padding: 0;
+ }
+
+ body.odoc {
+ display: block;
}
+
.odoc-toc {
position: static;
width: auto;
@@ -836,6 +1177,7 @@ td.def-doc *:first-child {
color: black;
background: white;
}
+
body nav:first-child {
visibility: hidden;
}
@@ -955,23 +1297,74 @@ td.def-doc *:first-child {
text-decoration: underline;
}
-.VAL, .TYPE, .LET, .REC, .IN, .OPEN, .NONREC, .MODULE, .METHOD, .LETOP, .INHERIT, .INCLUDE, .FUNCTOR, .EXTERNAL, .CONSTRAINT, .ASSERT, .AND, .END, .CLASS, .STRUCT, .SIG {
- color: #859900;;
-}
-
-.WITH, .WHILE, .WHEN, .VIRTUAL, .TRY, .TO, .THEN, .PRIVATE, .OF, .NEW, .MUTABLE, .MATCH, .LAZY, .IF, .FUNCTION, .FUN, .FOR, .EXCEPTION, .ELSE, .TO, .DOWNTO, .DO, .DONE, .BEGIN, .AS {
+.VAL,
+.TYPE,
+.LET,
+.REC,
+.IN,
+.OPEN,
+.NONREC,
+.MODULE,
+.METHOD,
+.LETOP,
+.INHERIT,
+.INCLUDE,
+.FUNCTOR,
+.EXTERNAL,
+.CONSTRAINT,
+.ASSERT,
+.AND,
+.END,
+.CLASS,
+.STRUCT,
+.SIG {
+ color: #859900;
+ ;
+}
+
+.WITH,
+.WHILE,
+.WHEN,
+.VIRTUAL,
+.TRY,
+.TO,
+.THEN,
+.PRIVATE,
+.OF,
+.NEW,
+.MUTABLE,
+.MATCH,
+.LAZY,
+.IF,
+.FUNCTION,
+.FUN,
+.FOR,
+.EXCEPTION,
+.ELSE,
+.TO,
+.DOWNTO,
+.DO,
+.DONE,
+.BEGIN,
+.AS {
color: #cb4b16;
}
-.TRUE, .FALSE {
+.TRUE,
+.FALSE {
color: #b58900;
}
-.failwith, .INT, .SEMISEMI, .LIDENT {
+.failwith,
+.INT,
+.SEMISEMI,
+.LIDENT {
color: #2aa198;
}
-.STRING, .CHAR, .UIDENT {
+.STRING,
+.CHAR,
+.UIDENT {
color: #b58900;
}
@@ -997,4 +1390,4 @@ td.def-doc *:first-child {
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- ---------------------------------------------------------------------------*/
+ ---------------------------------------------------------------------------*/
\ No newline at end of file
diff --git a/dev/odoc.support/odoc_search.js b/dev/odoc.support/odoc_search.js
new file mode 100644
index 0000000..0dc659d
--- /dev/null
+++ b/dev/odoc.support/odoc_search.js
@@ -0,0 +1,66 @@
+/* The browsers interpretation of the CORS origin policy prevents to run
+ webworkers from javascript files fetched from the file:// protocol. This hack
+ is to workaround this restriction. */
+function createWebWorker() {
+ var searchs = search_urls.map((search_url) => {
+ let parts = document.location.href.split("/");
+ parts[parts.length - 1] = search_url;
+ return '"' + parts.join("/") + '"';
+ });
+ blobContents = ["importScripts(" + searchs.join(",") + ");"];
+ var blob = new Blob(blobContents, { type: "application/javascript" });
+ var blobUrl = URL.createObjectURL(blob);
+
+ var worker = new Worker(blobUrl);
+ URL.revokeObjectURL(blobUrl);
+
+ return worker;
+}
+
+var worker;
+var waiting = 0;
+
+function wait() {
+ waiting = waiting + 1;
+ document.querySelector(".search-snake").classList.add("search-busy");
+}
+
+function stop_waiting() {
+ if (waiting > 0) waiting = waiting - 1;
+ else waiting = 0;
+ if (waiting == 0) {
+ document.querySelector(".search-snake").classList.remove("search-busy");
+ }
+}
+
+document.querySelector(".search-bar").addEventListener("focus", (ev) => {
+ if (typeof worker == "undefined") {
+ worker = createWebWorker();
+ worker.onmessage = (e) => {
+ stop_waiting();
+ let results = e.data;
+ let search_results = document.querySelector(".search-result");
+ search_results.innerHTML = "";
+ let f = (entry) => {
+ let search_result = document.createElement("a");
+ search_result.classList.add("search-entry");
+ search_result.href = base_url + entry.url;
+ search_result.innerHTML = entry.html;
+ search_results.appendChild(search_result);
+ };
+ results.forEach(f);
+ let search_request = document.querySelector(".search-bar").value;
+ if (results.length == 0 && search_request != "") {
+ let no_result = document.createElement("div");
+ no_result.classList.add("search-no-result");
+ no_result.innerText = "No result...";
+ search_results.appendChild(no_result);
+ }
+ };
+ }
+});
+
+document.querySelector(".search-bar").addEventListener("input", (ev) => {
+ wait();
+ worker.postMessage(ev.target.value);
+});