1 {-# LANGUAGE OverloadedLists #-}
2 {-# LANGUAGE OverloadedStrings #-}
4 module Language.FrenchSpec where
6 import Data.ByteString.Builder qualified as ByteString.Builder
7 import Data.Char qualified as Char
8 import Data.GenValidity.Map ()
9 import Data.GenValidity.Sequence ()
10 import Data.GenValidity.Set ()
11 import Data.GenValidity.Text ()
12 import Data.List qualified as List
13 import Data.Map.Strict qualified as Map
14 import Data.Set qualified as Set
15 import Data.Text qualified as Text
16 import Data.Text.Encoding qualified as Text
17 import Data.Text.Lazy.Encoding qualified as Text.Lazy
18 import Data.Text.Short qualified as ShortText
19 import Data.Validity.Map ()
20 import Data.Validity.Set ()
21 import Data.Validity.Text ()
23 import Language.French qualified as French
24 import Language.Pronunciation (ExampleLiteral (..), Lexeme (..), Rule (..), RuleLexemes, after, before, begining, ending, meaning, occurence, rule, silent, word)
25 import Language.Pronunciation qualified as Pron
26 import Paths_worksheets qualified as Self
27 import System.Directory qualified as IO
28 import System.FilePath (joinPath, pathSeparator, (<.>), (</>))
29 import System.FilePath.Posix qualified as File
30 import System.IO qualified as IO
32 import Text.Blaze.Html5.Attributes qualified as HA
33 import Utils.Pronunciation qualified as Pron
35 import Wiktionary qualified
36 import Worksheets.Utils.HTML (Html, className, classes, cm, styles, (!))
37 import Worksheets.Utils.HTML qualified as HTML
38 import Worksheets.Utils.IPA qualified as IPA
39 import Worksheets.Utils.Paper qualified as Paper
40 import Worksheets.Utils.Prelude
41 import Worksheets.Utils.SQL qualified as SQL
42 import Prelude (error, even, mod)
45 instance IsString Rule where
46 fromString s = rule {ruleLexemes = fromString s}
47 [ ful "de" := single "də" ["de" & occurence]
48 , inf "'" := single "" []
49 , inf "-" := single "" []
50 , inf "," := single "" []
51 , inf "?" := single "" []
52 , inf "!" := single "" []
53 , inf borderLeftText := single "" []
54 , inf borderRightText := single "" []
56 , inf "demi" := single "dəmi" ["demi" & occurence]
57 , -- , inf "amb" := single "ɑ̃b" ["amb" & occurence, "ulance"]
58 -- , inf "amp" := single "ɑ̃p" ["amp" & occurence, "oule"]
59 -- , inf "amph" := single "ɑ̃f" ["amph" & occurence, "ithéâtre"]
60 -- , inf "an" := multi
61 -- [ [PronContextBeforeBorder] := LexemePron{lexemePronunciation="ɑ̃", lexemeExample=["pl", "an" & occurence]}
62 -- , [PronContextBeforeAnyVowel] := LexemePron{lexemePronunciation="an", lexemeExample=["an" & occurence, "imal"]}
63 -- , [PronContextBeforeAny] := LexemePron{lexemePronunciation="ɑ̃", lexemeExample=["an" & occurence, "tilope"]}
65 , -- , inf "coin" := single "kwɛ̃" ["coin" & occurence, "cer"]
69 -- [ [PronContextBeforeBorder] := LexemePron{lexemePronunciation = "", lexemeExample = }
70 -- , [PronContextBeforeAnyVowel] := LexemePron{lexemePronunciation = "im", lexemeExample = ["im" & occurence, "ortel"]}
71 -- , [PronContextBeforeAny] := LexemePron{lexemePronunciation = "ɛ̃", lexemeExample = ["im" & occurence, "primer"]}
73 , -- , inf "in" := single "ɛ̃" ["merl", "in" & occurence]
74 -- , inf "ina" := single "ina" ["ord", "ina" & occurence, "teur"]
75 -- , inf "ine" := single "in" ["rout", "ine" & occurence]
76 -- , inf "inent" := single "in" ["dess", "inent" & occurence]
77 -- , inf "iner" := single "inɛʁ" ["iner" & occurence, "tie"]
78 -- , inf "inex" := single "inɛgz" ["inex" & occurence, "istant"]
79 -- , inf "inexp" := single "inɛksp" ["inexp" & occurence, "licable"]
80 -- , inf "inima" := single "inima" ["inima" & occurence, "ginable"]
81 -- , inf "inimi" := single "inimi" ["inimi" & occurence, "table"]
82 -- , inf "inimp" := single "inimp" ["inimp" & occurence, "ortant"]
83 -- , inf "ininf" := single "inɛ̃" ["ininf" & occurence, "lammation"]
84 -- , inf "inint" := single "inɛ̃t" ["inint" & occurence, "éressant"]
85 -- , inf "inn" := single "in" ["inn" & occurence, "ocent"]
86 -- , inf "ino" := single "ino" ["ino" & occurence, "dore"]
87 -- , inf "inu" := single "inu" ["inu" & occurence, "tile"]
88 -- , inf "ix" := single "iks" ["phén", "ix" & occurence]
89 -- , inf "gine" := single "ʒin" ["an", "gine" & occurence]
90 -- , inf "era" := single "əʁa" ["s", "era" & occurence]
91 -- , inf "erai" := single "əʁɛ" ["s", "erai" & occurence]
94 [ [PronContextBeforeAnyVowel] := LexemePron{lexemePronunciation = "əʁ", lexemeExample = ["mer" & occurence, "ingue"]}
95 , [PronContextBeforeAny] := LexemePron{lexemePronunciation = "ɛʁ", lexemeExample = ["mer" & occurence, "le"]}
97 , inf "erin" := single "əʁɛ̃" ["m", "erin" & occurence, "gue"]
100 [ [PronContextBeforeAnyVowel] := LexemePron{lexemePronunciation = "z", lexemeExample = ["ti", "s" & occurence, "ane"]}
101 , [PronContextBeforeAnySemiVowel] := LexemePron{lexemePronunciation = "z", lexemeExample = ["pari", "s" & occurence, "ienne"]}
102 , [PronContextBeforeAny] := LexemePron{lexemePronunciation = "s", lexemeExample = ["s", "a" & occurence]}
104 , -- , inf "shirt" := single "ʃœʁt" ["shirt" & occurence]
105 , -- , inf "teau" := single "to" ["teau" & occurence]
106 -- , inf "ti" := single "ti" ["ti" & occurence, "gre"]
107 , pre "ukulele" := single "jukulele" ["ukulele" & occurence]
108 , -- , inf "ui" := single "ɥi" ["ling", "ui" & occurence, "stique"]
109 , pre "abrivent" := single "abʁivɑ̃" ["abrivent" & occurence]
110 , pre "adjuvent" := single "adʒyvɑ̃" ["adjuvent" & occurence]
111 , pre "antivent" := single "ɑ̃tivɑ̃" ["antivent" & occurence]
112 , pre "auvent" := single "ovɑ̃" ["auvent" & occurence]
113 , pre "avent" := single "avɑ̃" ["avent" & occurence]
114 , pre "aï" := single "ai" ["c", "aï" & occurence, "man"]
115 , pre "bavent" := single "bavɑ̃" ["bavent" & occurence]
116 , pre "boutavent" := single "butavɑ̃" ["boutavent" & occurence]
117 , pre "bouvent" := single "buvɑ̃" ["bouvent" & occurence]
118 , pre "bénévent" := single "benevɑ̃" ["bénévent" & occurence]
119 , pre "connivent" := single "konivɑ̃" ["connivenr" & occurence]
120 , pre "contrevent" := single "kɔ̃tʁəvɑ̃" ["contrevent" & occurence]
121 , pre "convent" := single "kɔ̃vɑ̃" ["convent" & occurence]
122 , pre "couvent" := single "kuvɑ̃" ["couvent" & occurence]
123 , pre "couvents" := single "kuvɑ̃" ["couvents" & occurence]
124 , pre "engoulevent" := single "ɑ̃gulvɑ̃" ["engoulevent" & occurence]
125 , pre "fervent" := single "fɛʁvɑ̃" ["fervent" & occurence]
126 , pre "frévent" := single "fʁevɑ̃" ["frévent" & occurence]
127 , pre "heurtevent" := single "œʁtəvɑ̃" ["heurtevent" & occurence]
128 , pre "her" := single "ɛʁ" ["her" & occurence, "be"]
129 , pre "hi" := single "i" ["hi" & occurence, "ver"]
130 , pre "ill" := single "il" ["ill" & occurence, "étrisme"]
131 , pre "jack" := single "dʒak" ["jack" & occurence]
132 , pre "jazz" := single "dʒaz" ["jazz" & occurence]
133 , pre "montsurvent" := single "mɔ̃syʁvɑ̃" ["montsurvent" & occurence]
134 , -- , pre "ni" := single "ni" ["ni" & occurence, "ais"]
135 pre "niai" := single "njɛ" ["niai" & occurence, "s"]
136 , pre "paravent" := single "paʁavɑ̃" ["paravent" & occurence]
139 [ [PronContextBeforeAny] := LexemePron{lexemePronunciation = "sɑ̃", lexemeExample = ["sen" & occurence, "t"]}
140 , [PronContextBeforeAnyVowel] := LexemePron{lexemePronunciation = "sen", lexemeExample = ["sen" & occurence, "a"]}
141 -- , inf "a" := LexemePron{lexemePronunciation="sen", lexemeExample=["sen" & occurence, "a"]}
142 -- , inf "e" := LexemePron{lexemePronunciation="sən", lexemeExample=["sen" & occurence, "estre"]}
143 -- , inf "i" := LexemePron{lexemePronunciation="sen", lexemeExample=["sen" & occurence, "ior"]}
144 -- , inf "o" := LexemePron{lexemePronunciation="sen", lexemeExample=["Sen" & occurence, "oueix"]}
145 -- , inf "u" := LexemePron{lexemePronunciation="sen", lexemeExample=[]}
147 , pre "souvent" := single "suvɑ̃" ["souvent" & occurence]
148 , pre "taillevent" := single "tɑjvɑ̃" ["taillevent" & occurence]
149 , pre "tournevent" := single "tuʁnəvɑ̃" ["tournevent" & occurence]
150 , pre "vent" := single "vɑ̃" ["vent" & occurence]
151 , pre "virevent" := single "viʁvɑ̃" ["virevent" & occurence]
152 , pre "volvent" := single "vɔlvɑ̃" ["volvent" & occurence]
153 , pre "évent" := single "evɑ̃" ["évent" & occurence]
154 , pre "œ" := single "œ" ["œ" & occurence, "uf"]
155 , pre "fier" := single "fjɛʁ" ["fier" & occurence]
156 , pre "tier" := single "tjɛʁ" ["tier" & occurence]
160 & foldMap (\(ks, v) -> [(k, v) | k <- ks])
161 & mapFromListCheckingDuplicates
164 Map.singleton PronContextBeforeAny $ LexemePron{lexemePronunciation = pron, lexemeExample = exs}
168 & foldMap (\(ks, v) -> [(k, v) | k <- ks])
169 & mapFromListCheckingDuplicates
172 spec :: HasCallStack => Spec
174 -- Pron.lexerRender $ French.pronunciationDict
175 describe "pronunciation" do
176 -- describe "decomposition" do
177 -- forM_ sentences \sentence ->
178 -- Pron.pronunciationDecompositionTest French.pronunciationDict $ sentence & Text.unpack
179 -- describe "result" do
180 -- forM_ sentences \sentence ->
181 -- Pron.pronunciationResultTest French.pronunciationDict $ sentence & Text.unpack
183 Pron.pronunciationParserTest pronunciationRules sentences
188 around (\k -> SQL.withConnection "data/langs/français/kaikki/wiktionary=fr.lang=fr.sqlite3" k) do
189 outDB <- goldenPath "wiktionary" "sqlite"
190 outDBExists <- IO.doesFileExist outDB & liftIO
191 when (outDBExists) do
192 IO.removeFile outDB & liftIO
195 SQL.withConnection outDB \outConn ->
196 k (wiktConn, outConn)
199 it "check-against-wiktionary" \(wiktConn, outConn) -> do
200 SQL.execute_ outConn $ "PRAGMA journal_mode = OFF"
201 SQL.execute_ outConn $ "PRAGMA synchronous = OFF"
202 SQL.execute_ outConn $ "CREATE TABLE IF NOT EXISTS results (exprLit TEXT NON NULL, wiktBroad TEXT NON NULL, wiktBroadSegments TEXT NON NULL, synthBroad TEXT NON NULL, synthExplain TEXT NON NULL)"
203 SQL.execute_ outConn $ "CREATE INDEX results__exprLit ON results (exprLit);"
204 SQL.execute_ outConn $ "CREATE INDEX results__wiktBroad ON results (wiktBroad);"
205 SQL.execute_ outConn $ "CREATE INDEX results__synthBroad ON results (synthBroad);"
206 SQL.execute_ outConn $ "CREATE TABLE IF NOT EXISTS errors (exprId INTEGER NON NULL, exprLit TEXT NON NULL, error TEXT NON NULL)"
209 "SELECT id,word,sounds FROM wiktionary WHERE lang_code='fr' LIMIT 1000"
214 , maybeWord :: Maybe Text
215 , sounds :: [Wiktionary.Sound]
220 case exprLit & Pron.run French.pronunciationRules of
224 "INSERT INTO errors (exprId, exprLit, error) VALUES (?,?,?)"
230 let synthExplain = lexemes <&> (\Pron.Pron{pronInput, pronRule} -> Pron.chars pronInput <> " → " <> show (Pron.rulePron pronRule)) & List.intercalate "; "
231 let synthBroad = lexemes & foldMap (Pron.pronRule >>> Pron.rulePron >>> Pron.pronunciationText)
232 forM_ sounds \Wiktionary.Sound{..} -> do
233 -- IO.hPrint IO.stderr (i, ident::Int, maybeWord)
235 Just (IPA.IPAPhons exprIPAs) -> do
237 IPA.IPAPhonemic exprBroad -> do
238 when (i `mod` 5000 == 0) do
239 IO.hPrint IO.stderr (i, exprLit, exprBroad)
242 "INSERT INTO results(exprLit, wiktBroad, wiktBroadSegments, synthBroad, synthExplain) VALUES(?,?,?,?,?);"
244 , exprBroad & IPA.ipaWordsToText Nothing
245 , exprBroad & IPA.dropSupraSegmentalFeatures & IPA.ipaWordsToText Nothing
249 IPA.IPAPhonError (_errMsg, _err) -> return ()
257 mangleSupraSegmentalFeatures :: [IPA.Syllable []] -> [[IPA.Segment]]
258 mangleSupraSegmentalFeatures = \case
260 IPA.Syllable syl : ts -> syl : mangleSupraSegmentalFeatures ts
261 IPA.WithSuprasegmentalFeature IPA.Linking syl : ts ->
262 case mangleSupraSegmentalFeatures ts of
263 [] -> [dropSupraSegmentalFeatures syl]
264 x : xs -> (dropSupraSegmentalFeatures syl <> x) : xs
265 IPA.WithSuprasegmentalFeature _feat syl : xs ->
266 mangleSupraSegmentalFeatures (syl : xs)
269 -- cardsHtml "syllabes" $ French.syllablesTable & French.syllablesTableToHTML
271 sentences :: Map Pron.InputLexemes Pron.Pronunciation
277 -- , ["couvent"{exampleLiteralMeaning = "couver"}]
278 -- , ["couvent"{exampleLiteralMeaning = "monastère"}]
285 & Map.unionsWith (curry errorShow)
286 pronunciationRules :: Pron.Table
288 [ "Escherichia" := Rule{rulePron = ["E" := "ɛ", "sche" := "ʃe", "ri" := "ʁi", "chia" := "ʃja"], ruleExamples = ["Escherichia" := "ɛ.ʃe.ʁi.ʃja"]}
289 , "Maël" := Rule{rulePron = ["ma" := "ma", "ël" := "ɛl"], ruleExamples = ["Maël" := "ma.ɛl"]}
290 , "a" := Rule{rulePron = ["a" := "a"], ruleExamples = ["allume" := "a.lym"]}
291 , "ancrage" := Rule{rulePron = ["an" := "ɑ̃", "crage" := "kʁaʒ"], ruleExamples = ["ancrage" := "ɑ̃.kʁaʒ"]}
292 , "ancre" := Rule{rulePron = ["ancre" := "ɑ̃kʁ"], ruleExamples = ["ancre" := "ɑ̃kʁ"]}
293 , "ba" := Rule{rulePron = ["ba" := "ba"], ruleExamples = ["bateau" := "ba.to"]}
294 , "bain" := Rule{rulePron = ["bain" := "bɛ̃"], ruleExamples = ["bain" := "bɛ̃"]}
295 , "bile" := Rule{rulePron = ["bile" := "bil"], ruleExamples = ["immobile" := "i.mɔ.bil"]}
296 , "bo" := Rule{rulePron = ["bo" := "bɔ"], ruleExamples = ["bobo" := "bɔ.bo"]}
297 , "boi" := Rule{rulePron = ["boi" := "bwa"], ruleExamples = ["boit" := "bwa"]}
298 , "boué" := Rule{rulePron = ["boué" := "bwe"], ruleExamples = ["boué" := "bwe"]}
299 , "bri" := Rule{rulePron = ["bri" := "bʁi"], ruleExamples = ["sabrina" := "sa.bʁi.na"]}
300 , "brou" := Rule{rulePron = ["brou" := "bʁu"], ruleExamples = ["brouette" := "bʁu.ɛt"]}
301 , "ca" := Rule{rulePron = ["ca" := "ka"], ruleExamples = ["calla" := "ka.la"]}
302 , "cha" := Rule{rulePron = ["cha" := "ʃa"], ruleExamples = ["chamotté" := "ʃa.mɔ.te"]}
303 , "cham" <> [LexemeConsonant] := Rule{rulePron = ["cham" := "ʃɑ̃"], ruleExamples = ["champignon" := "ʃɑ̃.pi.ɲɔ̃"]}
304 , "chon" := Rule{rulePron = ["chon" := "ʃɔ̃"], ruleExamples = ["cochon" := "kɔ.ʃɔ̃"]}
305 , "chry" := Rule{rulePron = ["chry" := "kʁi"], ruleExamples = ["chrysanthème" := "kʁi.zɑ̃.tɛm"]}
306 , "ci" := Rule{rulePron = ["ci" := "si"], ruleExamples = ["mucidule" := "my.si.dyl"]}
307 , "cinthe" := Rule{rulePron = ["cinthe" := "sɛ̃t"], ruleExamples = ["jacinthe" := "ʒa.sɛ̃t"]}
308 , "co" := Rule{rulePron = ["co" := "kɔ"], ruleExamples = ["cochon" := "kɔ.ʃɔ̃"]}
309 , "de" := Rule{rulePron = ["de" := "də"], ruleExamples = ["demi" := "də.mi"]}
310 , "de" := Rule{rulePron = ["de" := "də"], ruleExamples = ["demi" := "də.mi"]}
311 , "deau" := Rule{rulePron = ["deau" := "do"], ruleExamples = ["rideau" := "ʁi.do"]}
312 , "dent" := Rule{rulePron = ["dent" := "dɑ̃"], ruleExamples = ["dent" := "dɑ̃"]}
313 , "deuil" := Rule{rulePron = ["deuil" := "dœj"], ruleExamples = ["deuil" := "dœj"]}
314 , "do" := Rule{rulePron = ["do" := "dɔ"], ruleExamples = ["doré" := "dɔ.ʁe"]}
315 , "drai" := Rule{rulePron = ["drai" := "dʁɛ"], ruleExamples = ["draisienne" := "dʁɛ.zjɛn"]}
316 , "du" := Rule{rulePron = ["du" := "dy"], ruleExamples = ["du" := "dy"]}
317 , "dule" := Rule{rulePron = ["dule" := "dyl"], ruleExamples = ["mucidule" := "my.si.dyl"]}
318 , "en" := Rule{rulePron = ["en" := "ɑ̃"], ruleExamples = ["en" := "ɑ̃"]}
319 , "ette" := Rule{rulePron = ["ette" := "ɛt"], ruleExamples = ["brouette" := "bʁu.ɛt"]}
320 , "fait" := Rule{rulePron = ["fait" := "fɛ"], ruleExamples = ["fait" := "fɛ"]}
321 , "feu" := Rule{rulePron = ["feu" := "fø"], ruleExamples = ["feu" := "fø"]}
322 , "feuille" := Rule{rulePron = ["feuille" := "fœj"], ruleExamples = ["feuille" := "fœj"]}
323 , "font" := Rule{rulePron = ["font" := "fɔ̃"], ruleExamples = ["font" := "fɔ̃"]}
324 , "fraise" := Rule{rulePron = ["fraise" := "fʁɛz"], ruleExamples = ["fraise" := "fʁɛz"]}
325 , "ga" := Rule{rulePron = ["ga" := "ga"], ruleExamples = ["alligator" := "a.li.ga.tɔʁ"]}
326 , "ge" := Rule{rulePron = ["ge" := "ʒə"], ruleExamples = ["gelée" := "ʒə.le"]}
327 , "geoir" := Rule{rulePron = ["geoir" := "ʒwaʁ"], ruleExamples = ["plongeoir" := "plɔ̃.ʒwaʁ"]}
328 , "geur" := Rule{rulePron = ["geur" := "ʒœʁ"], ruleExamples = ["nageur" := "na.ʒœʁ"]}
329 , "geuse" := Rule{rulePron = ["geuse" := "ʒøz"], ruleExamples = ["nageuse" := "na.ʒøz"]}
330 , "gi" <> [LexemeConsonant] := Rule{rulePron = ["gi" := "ʒi"], ruleExamples = ["gilet" := "ʒi.lɛ"]}
331 , "glace" := Rule{rulePron = ["glace" := "glas"], ruleExamples = ["glace" := "glas"]}
332 , "gnon" := Rule{rulePron = ["gnon" := "ɲɔ̃"], ruleExamples = ["champignon" := "ʃɑ̃.pi.ɲɔ̃"]}
333 , "gou" := Rule{rulePron = ["gou" := "gu"], ruleExamples = ["gouttière" := "gu.tjɛʁ"]}
334 , "gue" := Rule{rulePron = ["gue" := "gə"], ruleExamples = ["marguerite" := "maʁ.gə.ʁit"]}
335 , "gâ" := Rule{rulePron = ["gâ" := "ga"], ruleExamples = ["gâté" := "ga.te"]}
336 , "gée" := Rule{rulePron = ["gée" := "ʒe"], ruleExamples = ["orangée" := "ɔ.ʁɑ̃.ʒe"]}
337 , "hi" := Rule{rulePron = ["hi" := "i"], ruleExamples = ["hippopotame" := "i.pɔ.pɔ.tam"]}
338 , "ppo" := Rule{rulePron = ["ppo" := "pɔ"], ruleExamples = ["hippopotame" := "i.pɔ.pɔ.tam"]}
339 , "tame" := Rule{rulePron = ["tame" := "tam"], ruleExamples = ["hippopotame" := "i.pɔ.pɔ.tam"]}
340 , "ho" := Rule{rulePron = ["ho" := "o"], ruleExamples = ["homo" := "o.mo"]}
341 , "hêtre" := Rule{rulePron = ["hêtre" := "ɛtʁ"], ruleExamples = ["hêtre" := "ɛtʁ"]}
342 , "i" := Rule{rulePron = ["i" := "i"], ruleExamples = ["ibis" := "i.bis"]}
343 , "illet" := Rule{rulePron = ["illet" := "jɛ"], ruleExamples = ["œillet" := "œ.jɛ"]}
344 , "illo" := Rule{rulePron = ["illo" := "jo"], ruleExamples = ["maillot" := "ma.jo"]}
345 , "ja" := Rule{rulePron = ["ja" := "ʒa"], ruleExamples = ["jacinthe" := "ʒa.sɛ̃t"]}
346 , "jas" := Rule{rulePron = ["jas" := "ʒas"], ruleExamples = ["jasmin" := "ʒas.mɛ̃"]}
347 , "je" := Rule{rulePron = ["je" := "ʒə"], ruleExamples = ["jetée" := "ʒə.te"]}
348 , "jon" <> [LexemeConsonant] := Rule{rulePron = ["jon" := "ʒɔ̃"], ruleExamples = ["jonquille" := "ʒɔ̃.kij"]}
349 , "ju" := Rule{rulePron = ["ju" := "ʒy"], ruleExamples = ["judo" := "ʒy.do"]}
350 , "kan" := Rule{rulePron = ["kan" := "kɑ̃"], ruleExamples = ["kangourou" := "kɑ̃.gu.ʁu"]}
351 , "gou" := Rule{rulePron = ["gou" := "gu"], ruleExamples = ["kangourou" := "kɑ̃.gu.ʁu"]}
352 , "rou" := Rule{rulePron = ["rou" := "ʁu"], ruleExamples = ["kangourou" := "kɑ̃.gu.ʁu"]}
353 , "la" := Rule{rulePron = ["la" := "la"], ruleExamples = ["la" := "la"]}
354 , "langue" := Rule{rulePron = ["langue" := "lɑ̃g"], ruleExamples = ["langue" := "lɑ̃g"]}
355 , "le" := Rule{rulePron = ["le" := "lə"], ruleExamples = ["le" := "lə"]}
356 , "li" := Rule{rulePron = ["li" := "li"], ruleExamples = ["pissenlit" := "pi.sɑ̃.li"]}
357 , "lier" := Rule{rulePron = ["lier" := "lje"], ruleExamples = ["voilier" := "vwa.lje"]}
358 , "lin" <> [LexemeBorder] := Rule{rulePron = ["lin" := "lɛ̃"], ruleExamples = ["merlin" := "mɛʁ.lɛ̃"]}
359 , "lion" := Rule{rulePron = ["lion" := "ljɔ̃"], ruleExamples = ["lion" := "ljɔ̃"]}
360 , "lla" := Rule{rulePron = ["lla" := "la"], ruleExamples = ["calla" := "ka.la"]}
361 , "lli" := Rule{rulePron = ["lli" := "li"], ruleExamples = ["alligator" := "a.li.ga.tɔʁ"]}
362 , "llon" := Rule{rulePron = ["llon" := "jɔ̃"], ruleExamples = ["papillon" := "pa.pi.jɔ̃"]}
363 , "llume" := Rule{rulePron = ["llume" := "lym"], ruleExamples = ["allume" := "a.lym", "allume-feu" := "a.lym.fø"]}
364 , "lu" := Rule{rulePron = ["lu" := "ly"], ruleExamples = ["révolution" := "ʁe.vɔ.ly.sjɔ̃"]}
365 , "ly" := Rule{rulePron = ["ly" := "li"], ruleExamples = ["polypore" := "pɔ.li.pɔʁ"]}
366 , "lé" := Rule{rulePron = ["lé" := "le"], ruleExamples = ["gelé" := "ʒə.le"]}
367 , "ma" := Rule{rulePron = ["ma" := "ma"], ruleExamples = ["ma" := "ma"]}
368 , "mar" <> [LexemeConsonant] := Rule{rulePron = ["mar" <> [LexemeConsonant] := "maʁ"], ruleExamples = ["marguerite" := "maʁ.gə.ʁit"]}
369 , "masque" := Rule{rulePron = ["masque" := "mask"], ruleExamples = ["masque" := "mask"]}
370 , "mer" <> [LexemeConsonant] := Rule{rulePron = ["mer" <> [LexemeConsonant] := "mɛʁ"], ruleExamples = ["merlin" := "mɛʁ.lɛ̃"]}
371 , "mi" := Rule{rulePron = ["mi" := "mi"], ruleExamples = ["demi" := "də.mi"]}
372 , "mmo" := Rule{rulePron = ["mmo" := "mɔ"], ruleExamples = ["immobile" := "i.mɔ.bil"]}
373 , "mo" := Rule{rulePron = ["mo" := "mɔ"], ruleExamples = ["moto" := "mɔ.to"]}
374 , "mu" := Rule{rulePron = ["mu" := "my"], ruleExamples = ["mucidule" := "my.si.dyl"]}
375 , "mène" := Rule{rulePron = ["mène" := "mɛn"], ruleExamples = ["promène" := "pʁɔ.mɛn"]}
376 , "mènent" := Rule{rulePron = ["mènent" := "mɛn"], ruleExamples = ["promènent" := "pʁɔ.mɛn"]}
377 , "na" := Rule{rulePron = ["na" := "na"], ruleExamples = ["na" := "na"]}
378 , "nette" := Rule{rulePron = ["nette" := "nɛt"], ruleExamples = ["lunette" := "ly.nɛt", "lunettes" := "ly.nɛt"]}
379 , "niche" := Rule{rulePron = ["niche" := "niʃ"], ruleExamples = ["péniche" := "pe.niʃ"]}
380 , "nnet" := Rule{rulePron = ["nnet" := "nɛ"], ruleExamples = ["bonnet" := "bɔ.nɛ"]}
381 , "noc" := Rule{rulePron = ["noc" := "nɔk"], ruleExamples = ["nocturne" := "nɔk.tyʁn"]}
382 , "nou" := Rule{rulePron = ["nou" := "nu"], ruleExamples = ["nourrit" := "nu.ʁi"]}
383 , "o" := Rule{rulePron = ["o" := "ɔ"], ruleExamples = ["orange" := "ɔ.ʁɑ̃ʒ"]}
384 , "ou" := Rule{rulePron = ["ou" := "u"], ruleExamples = ["ou" := "u"]}
385 , "pa" := Rule{rulePron = ["pa" := "pa"], ruleExamples = ["papillon" := "pa.pi.jɔ̃"]}
386 , "paque" := Rule{rulePron = ["paque" := "pak"], ruleExamples = ["paquebot" := "pak.bo"]}
387 , "passe" := Rule{rulePron = ["passe" := "pas"], ruleExamples = ["passerelle" := "pas.ʁɛl"]}
388 , "pi" := Rule{rulePron = ["pi" := "pi"], ruleExamples = ["papillon" := "pa.pi.jɔ̃"]}
389 , "pi" := Rule{rulePron = ["pi" := "pi"], ruleExamples = ["pissenlit" := "pi.sɑ̃.li"]}
390 , "plon" := Rule{rulePron = ["plon" := "plɔ̃"], ruleExamples = ["plongeoir" := "plɔ̃.ʒwaʁ"]}
391 , "pneu" := Rule{rulePron = ["pneu" := "pnø"], ruleExamples = ["pneumatique" := "pnø.ma.tik"]}
392 , "po" := Rule{rulePron = ["po" := "pɔ"], ruleExamples = ["polypore" := "pɔ.li.pɔʁ"]}
393 , "pore" := Rule{rulePron = ["pore" := "pɔʁ"], ruleExamples = ["polypore" := "pɔ.li.pɔʁ"]}
394 , "porte" := Rule{rulePron = ["porte" := "pɔʁt"], ruleExamples = ["porte" := "pɔʁt"]}
395 , "pro" := Rule{rulePron = ["pro" := "pʁɔ"], ruleExamples = ["promène" := "pʁɔ.mɛn"]}
396 , "pâ" := Rule{rulePron = ["pâ" := "pa"], ruleExamples = ["pâquerette" := "pa.kʁɛt"]} -- ɑ
397 , "pé" := Rule{rulePron = ["pé" := "pe"], ruleExamples = ["péniche" := "pe.niʃ"]}
398 , "que" := Rule{rulePron = ["que" := "kə"], ruleExamples = ["querelle" := "kə.ʁɛl"]}
399 , "querette" := Rule{rulePron = ["querette" := "kʁɛt"], ruleExamples = ["pâquerette" := "pa.kʁɛt"]}
400 , "queuse" := Rule{rulePron = ["queuse" := "køz"], ruleExamples = ["visqueuse" := "vis.køz"]}
401 , "quille" := Rule{rulePron = ["quille" := "kij"], ruleExamples = ["jonquille" := "ʒɔ̃.kij"]}
402 , "quipe" := Rule{rulePron = ["quipe" := "kip"], ruleExamples = ["équipe" := "e.kip"]}
403 , "range" := Rule{rulePron = ["range" := "ʁɑ̃ʒ"], ruleExamples = ["orange" := "ɔ.ʁɑ̃ʒ"]}
404 , "relle" := Rule{rulePron = ["relle" := "ʁɛl"], ruleExamples = ["passerelle" := "pas.ʁɛl"]}
405 , "ri" := Rule{rulePron = ["ri" := "ʁi"], ruleExamples = ["rideau" := "ʁi.do"]}
406 , "rine" := Rule{rulePron = ["rine" := "ʁin"], ruleExamples = ["marine" := "ma.ʁin"]}
407 , "rite" := Rule{rulePron = ["rite" := "ʁit"], ruleExamples = ["marguerite" := "maʁ.gə.ʁit"]}
408 , "ro" := Rule{rulePron = ["ro" := "rɔ"], ruleExamples = ["robot" := "rɔ.bo"]}
409 , "rou" := Rule{rulePron = ["rou" := "ʁu"], ruleExamples = ["rouler" := "ʁu.le"]}
410 , "rouge" := Rule{rulePron = ["rouge" := "ʁuʒ"], ruleExamples = ["rouge" := "ʁuʒ"]}
411 , "rri" := Rule{rulePron = ["rri" := "ʁi"], ruleExamples = ["nourrit" := "nu.ʁi"]}
412 , "ré" := Rule{rulePron = ["ré" := "ʁe"], ruleExamples = ["révolution" := "ʁe.vɔ.ly.sjɔ̃"]}
413 , "sa" := Rule{rulePron = ["sa" := "sa"], ruleExamples = ["satellite" := "sa.te.lit"]}
414 , "sauve" := Rule{rulePron = ["sauve" := "sov"], ruleExamples = ["sauvetage" := "sov.taʒ"]}
415 , "scine" := Rule{rulePron = ["scine" := "sin"], ruleExamples = ["piscine" := "pi.sin"]}
416 , "short" := Rule{rulePron = ["short" := "ʃɔʁt"], ruleExamples = ["short" := "ʃɔʁt"]}
417 , "ssen" := Rule{rulePron = ["ssen" := "sɑ̃"], ruleExamples = ["pissenlit" := "pi.sɑ̃.li"]}
418 , "sur" := Rule{rulePron = ["sur" := "syʁ"], ruleExamples = ["sur" := "syʁ"]}
419 , "ta" := Rule{rulePron = ["ta" := "ta"], ruleExamples = ["ta" := "ta"]}
420 , "tage" := Rule{rulePron = ["tage" := "taʒ"], ruleExamples = ["sauvetage" := "sov.taʒ"]}
421 , "tan" <> [LexemeConsonant] := Rule{rulePron = ["tan" <> [LexemeConsonant] := "tɑ̃"], ruleExamples = ["tan" := "tɑ̃"]}
422 , "tellite" := Rule{rulePron = ["te" <> [LexemeDoubleConsonant] := "te", "llite" := "lit"], ruleExamples = ["satellite" := "sa.te.lit"]}
423 , "terie" := Rule{rulePron = ["terie" := "tʁi"], ruleExamples = ["poterie" := "pɔ.tʁi"]}
424 , "thème" := Rule{rulePron = ["thème" := "tɛm"], ruleExamples = ["chrysanthème" := "kʁi.zɑ̃.tɛm"]}
425 , "tient" := Rule{rulePron = ["tient" := "tjɛ̃"], ruleExamples = ["tient" := "tjɛ̃"]}
426 , "tier" := Rule{rulePron = ["tier" := "tje"], ruleExamples = ["chalutier" := "ʃa.ly.tje"]}
427 , "tion" := Rule{rulePron = ["tion" := "sjɔ̃"], ruleExamples = ["révolution" := "ʁe.vɔ.ly.sjɔ̃"]}
428 , "tique" := Rule{rulePron = ["tique" := "tik"], ruleExamples = ["pneumatique" := "pnø.ma.tik"]}
429 , "tire" := Rule{rulePron = ["tire" := "tiʁ"], ruleExamples = ["tire" := "tiʁ"]}
430 , "tor" := Rule{rulePron = ["tor" := "tɔʁ"], ruleExamples = ["alligator" := "a.li.ga.tɔʁ"]}
431 , "touche" := Rule{rulePron = ["touche" := "tuʃ"], ruleExamples = ["touche" := "tuʃ"]}
432 , "tris" <> [LexemeConsonant] := Rule{rulePron = ["tris" := "tʁis"], ruleExamples = ["ma" := "ma"]}
433 , "truffe" := Rule{rulePron = ["truffe" := "tʁyf"], ruleExamples = ["Truffe" := "tʁyf"]}
434 , "trône" := Rule{rulePron = ["trône" := "tʁon"], ruleExamples = ["trône" := "tʁon"]}
435 , "ttière" := Rule{rulePron = ["ttière" := "tjɛʁ"], ruleExamples = ["gouttière" := "gu.tjɛʁ"]}
436 , "tu" := Rule{rulePron = ["tu" := "ty"], ruleExamples = ["tuba" := "ty.ba"]}
437 , "turne" := Rule{rulePron = ["turne" := "tyʁn"], ruleExamples = ["nocturne" := "nɔk.tyʁn"]}
438 , "té" := Rule{rulePron = ["té" := "te"], ruleExamples = ["gâté" := "ga.te"]}
439 , "vache" := Rule{rulePron = ["vache" := "vaʃ"], ruleExamples = ["vache" := "vaʃ"]}
440 , "vec" := Rule{rulePron = ["vec" := "vɛk"], ruleExamples = ["avec" := "a.vɛk"]}
441 , "vis" := Rule{rulePron = ["vis" := "vis"], ruleExamples = ["visqueuse" := "vis.køz"]}
442 , "vo" := Rule{rulePron = ["vo" := "vɔ"], ruleExamples = ["révolution" := "ʁe.vɔ.ly.sjɔ̃"]}
443 , "voi" := Rule{rulePron = ["voi" := "vwa"], ruleExamples = ["voilier" := "vwa.lje"]}
444 , "vé" := Rule{rulePron = ["vé" := "ve"], ruleExamples = ["vélo" := "ve.lo"]}
445 , "yo" := Rule{rulePron = ["yo" := "jo"], ruleExamples = ["Yohan" := "jo.an"]}
446 , "é" := Rule{rulePron = ["é" := "e"], ruleExamples = ["équipe" := "e.kip"]}
447 , "œ" := Rule{rulePron = ["œ" := "œ"], ruleExamples = ["œillet" := "œ.jɛ"]}
448 , [LexemeVowel] <> "san" <> [LexemeConsonant] := Rule{rulePron = [[LexemeVowel] <> "san" <> [LexemeConsonant] := "zɑ̃"], ruleExamples = ["chrysanthème" := "kʁi.zɑ̃.tɛm"]}
449 , [LexemeVowel] <> "sienne" := Rule{rulePron = [[LexemeVowel] <> "sienne" := "zjɛn"], ruleExamples = ["draisienne" := "dʁɛ.zjɛn"]}
450 , [LexemeVowel] <> "ya" := Rule{rulePron = [[LexemeVowel] <> "ya" := "ja"], ruleExamples = ["ya" := "ja"]}
451 , begining "absent" := Rule{rulePron = [begining "ab" := "ab", "sent" := "sɑ̃"], ruleExamples = ["absent" := "ab.sɑ̃", "absents" := "ab.sɑ̃"]}
452 , begining "exer" := Rule{rulePron = ["e" := "ɛ", "x" := "g.z", "er" := "ɛʁ"], ruleExamples = ["exercice" := "ɛg.zɛʁ.sis"]}
453 , begining "ya" := Rule{rulePron = [begining "ya" := "ja"], ruleExamples = ["ya" := "ja"]}
454 , begining "yacht" := Rule{rulePron = ["yacht" := "jɔt"], ruleExamples = ["yacht" := "jɔt"]}
455 , ending "bis" := Rule{rulePron = [ending "bis" := "bis"], ruleExamples = ["ibis" := "i.bis"]}
456 , ending "bo" := Rule{rulePron = [ending "bo" := "bo"], ruleExamples = ["bobo" := "bɔ.bo"]}
457 , ending "bot" := Rule{rulePron = [ending "bot" := "bo"], ruleExamples = ["robot" := "rɔ.bo"]}
458 , ending "cice" := Rule{rulePron = [ending "cice" := ["sis"]], ruleExamples = ["exercice" := "ɛg.zɛʁ.sis"]}
459 , ending "cices" := Rule{rulePron = [ending "cices" := ["sis"]], ruleExamples = ["exercices" := "ɛg.zɛʁ.sis"]}
460 , ending "co" := Rule{rulePron = ["co" := "ko"], ruleExamples = ["cocorico" := "kɔ.kɔ.ʁi.ko"]}
461 , ending "do" := Rule{rulePron = [ending "do" := "do"], ruleExamples = ["judo" := "ʒy.do"]}
462 , ending "e" := Rule{rulePron = [ending "e" := [""]], ruleExamples = ["gelée" := "ʒə.le"]}
463 , ending "han" := Rule{rulePron = [ending "han" := "an"], ruleExamples = ["Yohan" := "jo.an"]}
464 , ending "ler" := Rule{rulePron = [ending "ler" := "le"], ruleExamples = ["rouler" := "ʁu.le"]}
465 , ending "let" := Rule{rulePron = [ending "let" := "lɛ"], ruleExamples = ["gilet" := "ʒi.lɛ"]}
466 , ending "lo" := Rule{rulePron = [ending "lo" := "lo"], ruleExamples = ["vélo" := "ve.lo"]}
467 , ending "min" := Rule{rulePron = [ending "min" := "mɛ̃"], ruleExamples = ["jasmin" := "ʒas.mɛ̃"]}
468 , ending "mmo" := Rule{rulePron = [ending "mmo" := "mo"], ruleExamples = ["immo" := "i.mo"]}
469 , ending "mo" := Rule{rulePron = [ending "mo" := "mo"], ruleExamples = ["homo" := "o.mo"]}
470 , ending "mot" := Rule{rulePron = [ending "mot" := "mo"], ruleExamples = ["mot" := "mo"]}
471 , ending "not" := Rule{rulePron = [ending "not" := "no"], ruleExamples = ["canot" := "ka.no"]}
472 , ending "s" := Rule{rulePron = [ending "s" := [""]], ruleExamples = []}
473 , ending "t" := Rule{rulePron = [ending "t" := [""]], ruleExamples = []}
474 , ending "tan" := Rule{rulePron = [ending "tan" := "tɑ̃"], ruleExamples = ["tan" := "tɑ̃"]}
475 , ending "teau" := Rule{rulePron = [ending "teau" := "to"], ruleExamples = ["bateau" := "ba.to"]}
476 , ending "to" := Rule{rulePron = [ending "to" := "to"], ruleExamples = ["moto" := "mɔ.to"]}
477 , ending "ts" := Rule{rulePron = [ending "ts" := [""]], ruleExamples = ["maillots" := "ma.jo"]}
478 , word "dans" := Rule{rulePron = [word "dans" := "dɑ̃"], ruleExamples = ["dans" := "dɑ̃"]}
479 , word "et" := Rule{rulePron = [word "et" := "e"], ruleExamples = ["et" := "e"]}
480 , word "les" := Rule{rulePron = [word "les" := "le"], ruleExamples = ["les" := "le"]}
481 , word "sous" := Rule{rulePron = [word "sous" := "su"], ruleExamples = ["sous" := "su"]}
482 , word "un" := Rule{rulePron = [word "un" := "œ̃"], ruleExamples = ["un" := "œ̃"]}
483 , word "une" := Rule{rulePron = [word "une" := "yn"], ruleExamples = ["une" := "yn"]}
484 , "coli" := Rule{rulePron = ["co" := "kɔ", "li" := "li"], ruleExamples = ["Escherichia coli" := "ɛ.ʃe.ʁi.ʃja.kɔ.li"]}
495 , ruleExamples = [["mer" & occurence]]
497 , begining "mer" <> [LexemeConsonant] :=
499 { rulePron = [ "mer" := ["mɛʁ"] ]
500 , ruleExamples = [["mer" & occurence, "le"]]
502 , begining "Mer" <> [LexemeConsonant] :=
504 { rulePron = [ "Mer" := ["mɛʁ"] ]
505 , ruleExamples = [["Mer" & occurence, "lin"]]
507 , begining "Mer" <> [LexemeConsonant] :=
509 { rulePron = [ "Mer" := ["mɛʁ"] ]
510 , ruleExamples = [["Mer" & occurence, "lin"]]
515 [ "ab" := ["ap"] -- sic
516 , "strait" := ["stʁɛ"]
518 , ruleExamples = [["abstrait" & occurence]]
522 { rulePron = ["ab" := ["ab"]]
523 , ruleExamples = [["ab" & occurence, "solu"]]
527 { rulePron = ["so" := ["sɔ"]]
528 , ruleExamples = [["ab", "so" & occurence, "lu"]]
532 { rulePron = ["lu" := ["ly"]]
533 , ruleExamples = [["lu" & occurence], ["abso", "lu" & occurence]]
537 { rulePron = ["a" := ["a"]]
538 , ruleExamples = [["a" & occurence]]
542 { rulePron = ["llume" := ["lym"]]
543 , ruleExamples = [["a", "llume" & occurence]]
550 , ruleExamples = [["exer", "cice" & occurence]]