From c8b49eed4cf92e7d2dd01dce779ef84ccae733eb Mon Sep 17 00:00:00 2001
From: Sébastien Dailly <sebastien@chimrod.com>
Date: Fri, 27 Aug 2021 14:37:24 +0200
Subject: Splitted modifiers in own library

---
 src/lib/modifiers/dune         |  3 +++
 src/lib/modifiers/modifiers.ml |  5 +++++
 src/lib/modifiers/mute.ml      | 18 ++++++++++++++++++
 src/lib/modifiers/nasal.ml     | 23 +++++++++++++++++++++++
 src/lib/modifiers/sig.ml       | 12 ++++++++++++
 src/lib/modifiers/vocalize.ml  | 20 ++++++++++++++++++++
 6 files changed, 81 insertions(+)
 create mode 100644 src/lib/modifiers/dune
 create mode 100644 src/lib/modifiers/modifiers.ml
 create mode 100644 src/lib/modifiers/mute.ml
 create mode 100644 src/lib/modifiers/nasal.ml
 create mode 100644 src/lib/modifiers/sig.ml
 create mode 100644 src/lib/modifiers/vocalize.ml

(limited to 'src/lib/modifiers')

diff --git a/src/lib/modifiers/dune b/src/lib/modifiers/dune
new file mode 100644
index 0000000..c1fb66c
--- /dev/null
+++ b/src/lib/modifiers/dune
@@ -0,0 +1,3 @@
+(library
+ (name modifiers)
+ (libraries sounds) )
diff --git a/src/lib/modifiers/modifiers.ml b/src/lib/modifiers/modifiers.ml
new file mode 100644
index 0000000..89e9485
--- /dev/null
+++ b/src/lib/modifiers/modifiers.ml
@@ -0,0 +1,5 @@
+module Sig = Sig
+
+let nasal = Nasal.process
+let vocalize_s = Vocalize.process
+let mute_consonant = Mute.process
diff --git a/src/lib/modifiers/mute.ml b/src/lib/modifiers/mute.ml
new file mode 100644
index 0000000..253df21
--- /dev/null
+++ b/src/lib/modifiers/mute.ml
@@ -0,0 +1,18 @@
+open StdLabels
+
+(** Mute the last consonant if there is no voyel in the syllabus.
+
+    This modifier is only applied in the first step, and not repeated anymore.
+*)let process
+  : 'a Sig.modifier
+  = fun (type el) m init ->
+    let module T = (val m:Sounds.T with type t = el) in
+    let (((v1, v2), c) , ending) = init in
+    let is_voyel = T.is_voyel v1 && T.is_voyel v2 in
+    match is_voyel, c with
+    | false, Some c ->
+      let c = { c with Sig.opening = List.map ~f:T.muted c.Sig.opening } in
+      (((v1, v2), Some c) , ending)
+    | _ -> init
+
+
diff --git a/src/lib/modifiers/nasal.ml b/src/lib/modifiers/nasal.ml
new file mode 100644
index 0000000..da24863
--- /dev/null
+++ b/src/lib/modifiers/nasal.ml
@@ -0,0 +1,23 @@
+(** The Nasal modifier transform a voyel followed by N and a consonant
+    into a nasal voyel.
+
+    Does this min that nasal voyel are not a distinct element, but just a
+    merge from two distinct elements ? *)
+let process
+  : 'a Sig.modifier
+  = fun (type el) m init ->
+    let module T = (val m:Sounds.T with type t = el) in
+    let (((v1, v2), c) , ending) = init in
+    let ending = Option.bind ending (fun x -> x) in
+    match ending with
+    | None -> init
+    | Some ending ->
+      match T.is_nasal ending with
+      | false -> init
+      | true ->
+        (* Remove the ending consonant, and transform the voyel into
+           the nasal form  *)
+        ( ( (T.nasal v1, T.nasal v2)
+          , c )
+        , None )
+
diff --git a/src/lib/modifiers/sig.ml b/src/lib/modifiers/sig.ml
new file mode 100644
index 0000000..938c50e
--- /dev/null
+++ b/src/lib/modifiers/sig.ml
@@ -0,0 +1,12 @@
+type 'a voyel = ('a * 'a)
+
+type 'a consonants =
+  { ending : 'a option option
+  ; opening : 'a list
+  ; following : 'a option }
+
+type 'a group = 'a voyel * 'a consonants option
+
+type 'a modifier = (module Sounds.T with type t = 'a) -> ('a group * 'a option option)  -> ('a group * 'a option option)
+
+
diff --git a/src/lib/modifiers/vocalize.ml b/src/lib/modifiers/vocalize.ml
new file mode 100644
index 0000000..86a0502
--- /dev/null
+++ b/src/lib/modifiers/vocalize.ml
@@ -0,0 +1,20 @@
+(** Transform the S into Z if the S is the opening consonant and
+    there is no ending consonant before *)
+let process
+  : 'a Sig.modifier
+  = fun (type el) m init ->
+    let module T = (val m:Sounds.T with type t = el) in
+    let (((v1, v2), c) , ending) = init in
+
+    match c with
+    | None -> init
+    | Some op ->
+      (* The voyel may be none in case of ending word. In such case, we shall
+         not trnasform the S into Z *)
+      let is_voyel = T.is_voyel v1 && T.is_voyel v2 in
+      match is_voyel, op.Sig.opening, op.Sig.ending with
+      | true, hd::[], None when T.code hd = T.SZ ->
+        let c = Some { op with opening = [T.z ()] } in
+        (((v1, v2), c) , ending)
+      | _ -> init
+
-- 
cgit v1.2.3