Afin d’éviter tout impair et de faciliter l’écriture politiquement correcte, voici un convertisseur qui transforme un texte en sa forme la plus inclusive qui soit; soit sa forme all inclusive.
Par exemple, la phrase:
Portez ce vieux whisky au juge blond qui fume.
qui contient toutes les lettres de base de l’alphabet latin est convertie en
P·o·r·t·e·z c·e v·i·e·u·x w·h·i·s·ky a·u j·u·g·e b·l·o·n·d q·u·i f·u·m·e.
Le convertisseur est fourni avec la fonction inverse qui permet de transformer un texte all inclusive dans sa forme macho.
Le programme est écrit en OCaml, langage de programmation déclaratif (vs. impératif) fonctionnel de type ML (Meta Language). De base, ce type de langage n’est pas fait pour manipuler des chaînes de caractères. La version d’OCaml utilisée ici ne gère qu’une partie du code ASCII et pas l’Unicode. Ce convertisseur est donc incomplet et n’est qu’une POC.
Il peut être testé sans installation compliquée et de manière interactive via un interpréteur OCaml toplevel: OCaml Toplevel for Android, Try OCaml, IOCamlJS Demos, …
Rem: comme OCaml gère très mal les Strings, certaines fonctions peuvent être deprecated, la bibliothèque d’I/O (Format) peut générer une erreur, … selon les (futures) versions du compilateur choisi. La logique du convertisseur reste cependant la même.
(* allinclusive : rend un texte politiquement correct *) (* explode, implode, totype & detype inspirés du code de INRIA *) (* Limite OCaml utilisé: ne fonctionne que pour le code ASCII printable (range (32..126)) *) (* TYPES *) type caractere = | Lettre of char | Autre of char ;; (* LIB *) let print texte = Format.printf "@[%s@]@." texte;; let explode s = let rec expl i l = if i < 0 then l else expl (i - 1) (s.[i] :: l) in expl (String.length s - 1) [];; let implode l = let result = String.create (List.length l) in let rec imp i = function | [] -> result | c :: l -> (String.set result i c); imp (i + 1) l in imp 0 l;; (* CONST *) let alphabet = "abcdefghijklmnopqrstuvwxuzABCDEFGHIJKLMNOPQRSTUVWXYZ";; let lettre = explode alphabet;; (* SUBS *) let totype texte = let rec expl i l = if i < 0 then l else expl (i - 1) ((if List.mem texte.[i] lettre then (Lettre texte.[i]) else (Autre texte.[i]))::l) in expl (String.length texte - 1) [] ;; let detype l = let result = String.create (List.length l) in let rec det i = function | [] -> result | (Lettre c | Autre c)::l -> (String.set result i c); det (i + 1) l in det 0 l ;; (* MAIN *) (* Et toutes ces manipulations de strings/bytes pour un pattern matching : *) let rec allinc t = match t with | [] -> [] | c::[] -> c::[] | (Autre c)::tail -> (Autre c)::(allinc tail) | (Lettre c1)::(Autre c2)::tail -> (Lettre c1)::(Autre c2)::(allinc tail) | (Lettre c1)::(Lettre c2)::tail -> (Lettre c1)::(Autre '\194')::(Autre '\183')::(allinc ((Lettre c2)::tail)) (* "\194\183" = "·" *) ;; let allinclusive texte = detype (allinc (totype texte));; (* REVERSE *) let rec toumach t = match t with | [] -> [] | c::[] -> c::[] | (Autre '\194')::(Autre '\183')::tail -> toumach tail | c::tail -> c::(toumach tail) ;; let toutmacho texte = detype (toumach (totype texte));; (* TEST *) let test = "Portez ce vieux whisky au juge blond qui fume.";; print test;; print (allinclusive test);; print (toutmacho (allinclusive test));;
L’exécution donne à l’écran (print):
Portez ce vieux whisky au juge blond qui fume. P·o·r·t·e·z c·e v·i·e·u·x w·h·i·s·ky a·u j·u·g·e b·l·o·n·d q·u·i f·u·m·e. Portez ce vieux whisky au juge blond qui fume.
Tandis que l’évaluation des expressions donne:
type caractere = Lettre of char | Autre of char val print : string -> unit = <fun> val explode : string -> char list = <fun> val implode : char list -> string = <fun> val alphabet : string = "abcdefghijklmnopqrstuvwxuzABCDEFGHIJKLMNOPQRSTUVWXYZ" val lettre : char list = ['a'; 'b'; 'c'; 'd'; 'e'; 'f'; 'g'; 'h'; 'i'; 'j'; 'k'; 'l'; 'm'; 'n'; 'o'; 'p'; 'q'; 'r'; 's'; 't'; 'u'; 'v'; 'w'; 'x'; 'u'; 'z'; 'A'; 'B'; 'C'; 'D'; 'E'; 'F'; 'G'; 'H'; 'I'; 'J'; 'K'; 'L'; 'M'; 'N'; 'O'; 'P'; 'Q'; 'R'; 'S'; 'T'; 'U'; 'V'; 'W'; 'X'; 'Y'; 'Z'] val totype : string -> caractere list = <fun> val detype : caractere list -> string = <fun> val allinc : caractere list -> caractere list = <fun> val allinclusive : string -> string = <fun> val toumach : caractere list -> caractere list = <fun> val toutmacho : string -> string = <fun> val test : string = "Portez ce vieux whisky au juge blond qui fume." - : unit = () - : unit = () - : unit = ()