Inhalt der Datei Hedda.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Speech.Synthesis;
using System.Text.RegularExpressions;


namespace Mittelhochdeutsches_Hörbuch1
{
    class Hedda
    {
        // Die Liste der von Hedda in Text vorgefundenen unbekannten Buchstaben:
        public List<char> UnbekannteZeichen = new List<char>();
    
  
      

        // Ein Lexion zur Aufnahme der abweichend auszusprechenden Wortformen:
        private Dictionary<string, string> Lexikon = new Dictionary<string, string>
        {
            ["rehtiu"] = "S1 R EH C . T Y lng",
            ["Genewîs"]="S2 G E lng . N EX . S1 V I lng S",
            ["tugenden"]="S1 T UH . G EX N . D EX N",
            ["manegen"]="S1 M AA . N EX . G EX N",
            ["maneger"]="S1 M AA . N EX . G EHX",
            ["mæzeclîchen"] = "S1 M EH lng . Z EX K . S2 L I lng . C EX N",
            ["künneschaft"] = "S1 K Y . N EX . S2 SH AA F T"

        };
        private Dictionary<string, string> LexikonDerPräfixe = new Dictionary<string, string>
        {
            ["be"] = "B EX",
            ["ge"] = "G EX",
            ["ver"] = "F EHX",
            ["zer"] = "Z EHX",
            ["en"] = "EH N",
            ["unbe"] = "S1 UH N . B EX",
            ["unge"] = "S1 UH N . G EX",
            ["unver"] = "S1 UH N . F EHX",
            ["unzer"] = "S1 UH N . Z EHX"

        };
        Dictionary<string, string> LexionDerBuchstabenErsetzung = new Dictionary<string, string>
        {
            ["î"] = "I lng",
            ["iu"] = "Y lng",
            ["ei"] = "E lng + IH",
            ["ie"] = "I lng + EH",
            ["a"] = "AA",
            ["â"]="AA lng",
            ["ä"]="A",
            ["ae"]="EH lng",
            ["æ"] ="EH lng",
            ["c"]="K", 
            ["ch"]="X",
            ["e"]="EH",
            ["ê"]="E lng",
            ["i"]="IH",
            ["o"]="O",
            ["ô"]="O lng",
            ["oe"]="EU",
            ["œ"] ="EU",
            ["ö"]="OE",
            ["ou"]="AO + UH",
            ["öu"]="OI",
            ["ph"]="P + F",
            ["sc"]="SH",
            ["sch"]="SH",
            ["u"] = "UH",
            ["û"]="U lng",
            ["uo"]="U lng + O",
            ["ü"]="YH",
            ["üe"]="Y lng + EH",
            ["w"]="v",
            ["v"]="f",
            ["z"]="T + S",
            ["zz"]="Z",
            // deutsche r-Laute:
            ["ür"]="UYX",
            ["or"]="OWX",
            ["ör"]="OE + AX",
            ["oer"]="EU lng + AX",
            ["œr"] = "EU lng + AX",
            ["er"]="EHX",
            ["ûr"]="UAX",
            ["aer"] = "EH lng + AX",
            ["ær"] = "EH lng + AX",
            // Satzzeichen:
            ["."]="_.",
            [","]="_,",
            [":"]="_.",
            [";"]="_,",
            ["?"]="_?",
            ["!"]="_!",
            // ht,lh,rh
            ["ht"]="X T",
            ["hs"]="X T",
            ["lh"]="L C",
            ["rh"]= "R C"

            // Weitere Ersetzungen folgen ...
        };
        List<string> Kurzwörter = new List<string>
        { "vor","von","der","diu","die","daz","diz","ditz",
            "den","dem","dan","und","in","im","ir",
            "an","ze","al","ez","für","ich","er","si",
            "wol","bî","hie","wi","wie","ein","niht",
            "mîn","sîn","mich","sich","doch","noch","nâch",
            "dar","zuo","ie","mit","mê", "ouch","nu","unz",
            "als","vil","wan","gar"
        };
        public void SchreibeLexikon()
        {
            Console.WriteLine("*** Lexikon ***");
            foreach (KeyValuePair<string, string> paar in Lexikon.OrderBy(paar => paar.Key)) Console.WriteLine(paar.Key + "=> [" + paar.Value + "]");
        }
        private int Silbenzahl(string Text)
        {
            Regex re = new Regex(@"[aâeêiîoôöuûüáéíóúàèìòùæœ]{1,2}");
            return re.Matches(Text).Count; 
        }
        private bool Klingend(string Zeile)
        {
            Regex reVersende =new Regex( @"ei|[bcdfghklmnprstvwz]e[rntlsz\.,;:\?!]{0,3}$");
            if (reVersende.Match(Zeile).Success)
            {
                // Wir akzeptieren das Resultat, wenn das letzte Wort von Zeile mehrsilbig ist:
                if (Silbenzahl(Zeile.Split().Last()) > 1) return true;
            }
            return false; // Alle anderen Fälle.
        }

        public string FindeAussprache(string Wort)
        {
            string Aussprache = "S1 "; //Default
            if (Kurzwörter.Contains(Wort)) Aussprache = ""; // Wenn das Wort nicht zu den meist unbetonten Kurzwörtern gehört!
            
            /* Wir überprüfen, ob die Möglichkeit einer präfigierenden Vorsilbe besteht.
             * Dazu muss das Wort mindestens vier Buchstaben und zwei Silben aufweisen:
             */
            if (Wort.Length>4 && Silbenzahl(Wort) > 1)
            {
                
                // Wir bauen die Suchanfrage auf:

                List<string> Präfixe = LexikonDerPräfixe.Keys.ToList();
                Präfixe.Sort((Präfix1, Präfix2) => Präfix2.Length.CompareTo(Präfix1.Length));
                string Suche = @"^(?<Präfix>" + String.Join("|", Präfixe) + ")";
                
                // Wir suchen. "Treffer" enthält die Suchergebnisse

                Regex reAnfang = new Regex(Suche);
                Match Treffer =  reAnfang.Match(Wort);

                if (Treffer.Success) // Wenn es einen Treffer gibt ...
                {
                    string Präfix = Treffer.Groups["Präfix"].ToString(); // ist dieser in Präfix gespeichert
                                                                        
                    // Erneute Überprüfung: Ist das gefundene Präfix zu lang?

                    if (Wort.Length-Präfix.Length > 2 && Silbenzahl(Wort.Substring(Präfix.Length))>0)
                    {
                        // Gut. Wir ersetzen.

                        Aussprache = LexikonDerPräfixe[Präfix] + " . S1 ";
                        Wort = Wort.Substring(Präfix.Length);
                    }  
                }
            }
           
            // Präfix oder nicht, jetzt wird die Aussprache des (Rest-)Wortes gefunden
            // Dieser Teil von FindeAussprache hat sich nicht geändert.

            int i = 0; // Index des Buchstabens, an dem wir uns gerade befinden.
            while (i<Wort.Length) // Solange i < als die Wortlänge ist.
            {
                List<string> MöglicheBuchstabenFolgen; 
                MöglicheBuchstabenFolgen = LexionDerBuchstabenErsetzung.Keys // Die mhd. Buchstabenfolgen
                                            .Where(Buchstaben => Buchstaben[0] == Wort[i]) // bei denen der erste Buchstabe und der aktuelle unseres Suchbegriffes identisch sind.
                                            .ToList();                         // als Liste.
                MöglicheBuchstabenFolgen.Sort((Folge1,Folge2)=>Folge2.Length.CompareTo(Folge1.Length)); // Sortiere die Liste absteigend nach ihrer Länge.

                /* Wir gehen die Buchstabenfolgen mit dem gesuchten Anfang,
                 * die der Länge nach, absteigend sortiert sind,
                 * eine nach der anderen durch und überprüfen,
                 * ob sie sich ganz an der Stelle i in unserem Wort finden.
                 * Wenn die erste (längste) Folge identifiziert wird,
                 * brechen wir die Suche ab und ersetzen.
                 * Andernfalls suchen wir weiter.*/
                bool Gefunden = false; // 
              
                    
                foreach (string Buchstabenfolge in MöglicheBuchstabenFolgen)
                {
                   
                    if (Wort.Length-i >= Buchstabenfolge.Length && Wort.Substring(i, Buchstabenfolge.Length) == Buchstabenfolge)
                    {
                        string Ersatz = LexionDerBuchstabenErsetzung[Buchstabenfolge];
                        if (Ersatz[0]=='X')
                        {
                            if (i - 1 >= 0 && "iîeêöüäœæ".Contains(Wort[i - 1])) Ersatz = "C";
                            if (i - 2 >= 0 && Wort.Substring(i-2,2)=="iu") Ersatz = "C";
                        }

                        if (Ersatz=="T + S")
                        {
                            if (i - 1 >= 0 && "aouâôûiîeêöüäœæ".Contains(Wort[i - 1])) Ersatz = "Z"; 
                        }
                        Aussprache += Ersatz; // X += Y ist X = X + Y
                        Aussprache += ' '; //nicht das Leerzeichen vergessen!
                        i +=  Buchstabenfolge.Length;
                        Gefunden = true;
                        break; // Ein Ersatz gefunden, wir suchen nicht mehr weiter!
                    }
                
                }
                if (!Gefunden)
                {
                    // Unbekannter Buchstabe
                    // Falls noch nicht in der Liste der unbekannten Zeichen,
                    // trage ihn ein.
                    if (!UnbekannteZeichen.Contains(Wort[i])) UnbekannteZeichen.Add(Wort[i]);
                    i += 1; // Zähle Weiter
                }
            }

            // Jetzt kümmern wir uns um das Ende des Wortes:

            if (Silbenzahl(Wort) > 1)
            {
               /* Wir fragen ab, ob eine unbetonte Endsilbe existieren kann und speichern das Ergebnis
                  Der ziemlich komplizierten Abfrage in vier Variablen:
                    Anfang - speichert den Beginn des Wortes VOR der Endsilbe
                    Links - speichert den linken Rand der Silbe.
                    Rechts - entsprechend den rechten Rand.
                    Satzzeichen - nimmt ein etwaiges Satzzeichen auf.
                    */

               
                Regex reEnde = new Regex(@"(?<Anfang>.+[^\.] )(?<Ei>E lng \+ IH )?(?<Links>(?(Ei)|(P \+ F |T \+ S |SH |[BCDFGHKLMNRSTVZ] )))EH (?<Rechts>N T |R T |L S |R S |[SZTRNK] )?(?<Satzzeichen>_[\.\,\?\!] )?$");

                Match Suffix = reEnde.Match(Aussprache);
               
               
                if (Suffix.Success)
                {
 
                    // Wenn unsere Suche Erfolg hatte, setzen wir das Ergebnis zusammen:
                  
                    Aussprache = Suffix.Groups["Anfang"]+"" + Suffix.Groups["Ei"] + ". "+Suffix.Groups["Links"] + " EX " + Suffix.Groups["Rechts"]+Suffix.Groups["Satzzeichen"];

                } 
                // Wir kümmern uns jetzt auch  um Wörter auf -er, bei denen das Ende EHX ist:
               
                reEnde = new Regex(@"(?<Anfang>.+[^\.] )(?<Ei>E lng \+ IH )?(?<Links>(?(Ei)|(P \+ F |T \+ S |SH |[BCDFGHKLMNRSTVZ] )))EHX (?<Rechts>[NTS] )?$");
                Suffix = reEnde.Match(Aussprache);
                if (Suffix.Success)
                {
 
                    // Wenn unsere Suche Erfolg hatte, setzen wir das Ergebnis zusammen:

                      Aussprache = Suffix.Groups["Anfang"] +""+ Suffix.Groups["Ei"]+ ". " + Suffix.Groups["Links"] + "EHX " + Suffix.Groups["Rechts"] + Suffix.Groups["Satzzeichen"];
             
                }
 
            }
       
            return Aussprache;
        } 
        public  void LeseZeile (string Zeile, PromptBuilder pb)
        {

            /* Los geht's Hedda!
             * Lies Wort für Wort.
             * Überprüfe, ob das Wort im Lexikon vermerkt wurde.
             * Wenn ja, dann folge der dort in Lautschrift notierten Aussprache.
             * Wenn nicht ... mach's wie immer, sprich so, wie es da "geschrieben" steht.*/

            int SilbenImVers = Silbenzahl(Zeile);
            int Silbe = 0;
           

            foreach (string w in Zeile.ToLower().Split(' '))
            {
                
                string Satzzeichen = ".,?!;:".Contains(w.Last()) ? w.Last().ToString():null;
                string Wort = Satzzeichen==null ? w:w.Substring(0, w.Length - 1);
                Silbe += Silbenzahl(Wort);

                if (Lexikon.Keys.Contains(Wort))
                {
                    string Sonderbetonung = "";
                    if (Kurzwörter.Contains(Wort))
                   { 
                        if ((SilbenImVers-Silbe) % 2 == 1 && Klingend(Zeile)) Sonderbetonung = "S1 " ;
                        if ((SilbenImVers-Silbe) % 2 == 0 && !Klingend(Zeile)) Sonderbetonung = "S1 "; 
                       
                    }
                    //Sonderfall, der im Lexikon gefunden wurde:
                    pb.AppendSsmlMarkup(@"<phoneme alphabet=""ups"" ph="""
                                        +Sonderbetonung
                                        + Lexikon[Wort] + @""">"// Die Lautschriftvariante
                                        + Wort + "</phoneme>");//  gefolgt von der Graphie  
                }
                else
                {
                    // Unbekanntes Wort, ermittel den Ausspracheregeln folgend die korrekte Lautung:
                    string Lautung = FindeAussprache(Wort);
                    if (Lautung != "")
                    {
                        Lexikon[Wort] = Lautung;
                        if (Kurzwörter.Contains(Wort))
                        {
                            if ((SilbenImVers-Silbe) % 2 == 1 && Klingend(Zeile)) Lautung = "S1 " + Lautung;
                            if ((SilbenImVers-Silbe) % 2 == 0 && !Klingend(Zeile)) Lautung = "S1 " + Lautung;
                           
                        }
                        
                        pb.AppendSsmlMarkup(@"<phoneme alphabet=""ups"" ph="""
                                            + Lautung + @""">"// Die Lautschriftvariante
                                            + Wort + "</phoneme>");//  gefolgt von der Graphie

                       
                    }
                }
                if (Satzzeichen != null)
                {
                    pb.AppendSsmlMarkup(@"<phoneme alphabet=""ups"" ph="""
                                             + LexionDerBuchstabenErsetzung[Satzzeichen] + @""">"// Die Lautschriftvariante
                                             + Satzzeichen + "</phoneme>");//  gefolgt von der Graphie
                    if (".?!".Contains(Satzzeichen))
                    { 
                       /* pb.EndSentence();
                        pb.AppendBreak(PromptBreak.ExtraSmall);
                        pb.StartSentence();*/
                    }
                   
                }
              
            }
            pb.AppendBreak(Klingend(Zeile)?PromptBreak.ExtraSmall:PromptBreak.Small);
           
        
        }
        public Hedda()
        {
            string EinfachBuchstaben = "bdfghjklmnprst";
            foreach(  char c in EinfachBuchstaben)
            {
                LexionDerBuchstabenErsetzung[c.ToString()] = c.ToString().ToUpper();
            }
 
        }
    }
  
}