def decodeTrennung(t):
    """Hyphenates a word whose hyphenation point are explicitly given.
       For example "play5er".
    """
    W = []
    p = 0
    for i in range(len(t)):
        if t[i] in "123456789":
            q = int(t[i])
            W.append(HyphenationPoint(p, q, 0, SHY, 0, u""))
        else:
            p += 1
    return W
 def zerlegeWort(self, zusgWort):
     hyphPoints = []
     for left, right in self.hnj.pairs(zusgWort):
         # Uncomment next line for an example of non-standard hyphenation
         # if left=="schif" and right=="fahrt": left="schiff"
         sl = self.shy
         if left[-1] in [u"-", self.shy]:
             sl = u""
         if left + right == zusgWort:
             hp = HyphenationPoint(len(left), self.quality, 0, sl, 0, u"")
         else:
             # Handle non-standard hyphenation
             # TODO: Test this.
             for i, ch in enumerate(left):
                 if ch != zusgWort[i]:
                     nl = len(left) - i
                     sl = left[i:] + sl
                     break
             else:
                 nl = 0
                 pos = len(left)
             thgir = list(right)
             thgir.reverse()
             for i, ch in enumerate(thgir):
                 if ch != zusgWort[-i - 1]:
                     nr = 0
                     sr = right[:-i - 1]
                     break
             else:
                 nr = 0
                 sr = right[:len(left) + len(right) - len(zusgWort)]
                 assert sr, (
                     "This should be handled via left+right==zusgWort",
                     left, right, zusgWort)
             hp = HyphenationPoint(len(left), self.quality, nl, sl, nr, sr)
         hyphPoints.append(hp)
     return hyphPoints
Exemple #3
0
 def hyph(self, word):
     log.debug("DCW hyphenate %r", word)
     assert isinstance(word, unicode)
     loesungen = self.zerlegeWort(word)
     if len(loesungen) > 1:
         # Trennung ist nicht eindeutig, z.B. bei WachsTube oder WachStube.
         #hword.info = ("AMBIGUOUS", loesungen)
         # nimm nur solche Trennstellen, die in allen Lösungen vorkommen,
         # und für die Qualität nimm die schlechteste.
         loesung = []
         loesung0, andere = loesungen[0], loesungen[1:]
         for i, hp in enumerate(loesung0):
             q = hp.quality
             for a in andere:
                 if q:
                     for hp1 in a:
                         if hp1.indx==hp.indx \
                         and hp1.nl==hp.nl and hp1.sl==hp.sl \
                         and hp1.nr==hp.nr and hp1.sr==hp.sr:
                             q = min(q, hp1.quality)
                             break
                     else:
                         # Trennstelle nicht in der anderen Lösung enthalten
                         q = 0
             if q:
                 loesung.append(
                     HyphenationPoint(hp.indx, q, hp.nl, hp.sl, hp.nr,
                                      hp.sr))
         if loesung:
             # Es gibt mindestens eine Trennstelle, die bei allen Varianten
             # enthalten ist, z.b. Wachstu-be.
             pass
             # hword.info = ("HYPHEN_OK", loesung)
         else:
             # Es gibt keine Trennstelle.
             pass
     elif len(loesungen) == 1:
         # Trennung ist eindeutig
         loesung = loesungen[0]
         #hword.info = ("HYPHEN_OK", loesung)
         if not loesung:
             pass  # hword.info = ("NOT_HYPHENATABLE", aWord)
     else:
         # Das Wort ist uns unbekannt.
         return None
     return HyphenatedWord(word, loesung)
Exemple #4
0
    def zerlegeWort(self, zusgWort, maxLevel=20):

        #Wort erstmal normalisieren
        assert isinstance(zusgWort, unicode)
        zusgWort = zusgWort.lower().replace(u'Ä', u'ä').replace(u'Ö',
                                                                u'ö').replace(
                                                                    u'Ü', u'ü')
        lenword = len(zusgWort)
        #print zusgWort
        loesungen = []

        L = self._zerlegeWort(zusgWort)
        # Trennung für Wortstämme mit Endungen berichtigen
        for W in L:
            # Eine mögliche Lösung. Von dieser die einzelnen Wörter betrachten
            Wneu = []
            offset = 0
            ok = True
            #log.debug ("Versuche %r", W)
            sr = ""
            for i, w in enumerate(W):
                if not ok: break
                offset += len(w.prefix_chars)
                if i > 0:
                    # @TODO: Hier darf nicht fest shy stehen, da
                    # das letzte Wort mit "-" geendet haben könnte
                    lastWordSuffixChars = W[i - 1].suffix_chars
                    if lastWordSuffixChars and lastWordSuffixChars[
                            len(lastWordSuffixChars) -
                            1][-1:] in [u"-", self.shy]:
                        Wneu.append(
                            HyphenationPoint(offset, self.qHaupt, 0, "", 0,
                                             sr))
                    else:
                        Wneu.append(
                            HyphenationPoint(offset, self.qHaupt, 0, self.shy,
                                             0, sr))
                if w.konsonantenverkuerzung_3_2:
                    sr = w.root.strval[-1]
                else:
                    sr = u""

                if w.prefix:
                    for f in w.prefix:
                        Wneu += self.schiebe(
                            offset, self.dudentrennung(f.strval,
                                                       self.qVorsilbe))
                        offset += len(f.strval)
                        Wneu.append(
                            HyphenationPoint(offset, 7, 0, self.shy, 0, u""))
                        # @TODO Qualität 7 ist hier fest eingebrannt
                for p in w.root.props:
                    if isinstance(p, TRENNUNG) or isinstance(p, KEEP_TOGETHER):
                        st = p.args
                        break
                else:
                    st = self.dudentrennung(w.root.strval, self.qSchlecht)
                if len(st):
                    Wneu += self.schiebe(offset, st)
                    st, stLast = st[:-1], st[-1]
                    p = stLast.indx
                    offset += p
                    en = w.root.strval[p:] + (u"".join(
                        [s.strval for s in w.suffix]))
                else:
                    en = w.root.strval + (u"".join(
                        [s.strval for s in w.suffix]))
                if w.suffix:
                    ent = self.dudentrennung(en, self.qNeben)
                    #print "en=",en,"ent=",ent
                    Wneu += self.schiebe(offset, ent)
                    # Prüfen, ob dieses Wort als letztes stehen muss
                #
                #for pf in w.prefix + [w.root] + w.suffix:
                #    if i>0 and pf.props.get(NOT_AFTER_WORD) and str(W[i-1].root) in pf.props.get(NOT_AFTER_WORD):
                #        if VERBOSE: print "'%s' nicht erlaubt nach '%s'" % (pf,W[i-1].root)
                #        ok = False
                #        break
                #    if pf.props.get(ONLY_LAST_WORD) and i<len(W)-1:
                #        if VERBOSE: print "'%s' nur als letztes Wort erlaubt!" % pf
                #        ok = False
                #        break
                #    if pf.props.get(ONLY_FIRST_WORD) and i>0:
                #        if VERBOSE: print "'%s' nur als erstes Wort erlaubt!" % pf
                #        ok = False
                #        break
                #else:
                #  # letztes Wort
                #  for pf in w.prefix + [w.root] + w.suffix:
                #    #print "letztes Wort, Bestandteil",pf, pf.props
                #    if pf.props.get(NOT_LAST_WORD):
                #        if VERBOSE: print "'%s' nicht als letztes Wort erlaubt!" % pf
                #        ok = False
                #        break
                offset += len(en)
                offset += len(w.suffix_chars)
            if ok and (Wneu not in loesungen):
                log.debug("Wneu=%r", Wneu)
                loesungen.append(Wneu)

        return loesungen
Exemple #5
0
    def dudentrennung(self, wort, quality=None):
        """ 
            The algorithm how to hyphenate a word
            without knowing about the context.

            This code is quite specific to German!
            For other languages, there may be totally different rules.
            
            This rule is known as "Ein-Konsonanten-Regel" in German.
            The rule works (basically) as follows:
            First, find the vowels in the word,
            as they mark the syllables (one hyphenation point between
            two vowels (but consider sequences of vowels counting as one).
            If there are consonants between two vowels,
            put all but the last consonant to the left syllable,
            and only the last consonant to the right syllable
            (therefore the name one-consonant-rule).
            However, there are also sequences of consonants counting as one,
            like "ch" or "sch".
        """
        #print "dudentrennung: %s" % wort
        if not quality: quality = self.qNeben

        assert isinstance(wort, unicode)

        # Jede Silbe muss mindestens einen Vokal enthalten
        if len(wort) <= 2:
            return []
        # Suche bis zum ersten Vokal
        for vpos1 in range(len(wort)):
            if wort[vpos1] in VOWELS:
                if wort[vpos1 - 1:vpos1 + 1] != 'qu':
                    break
        else:
            # Kein Vokal enthalten!
            return []
        # wort[vpos1] ist der erste Vokal
        fertig = False
        stpos = vpos1 + 1
        while not fertig:
            fertig = True
            # Suche bis zum zweiten Vokal
            for vpos2 in range(stpos, len(wort)):
                if wort[vpos2] in VOWELS:
                    break
            else:
                # Kein zweiter Vokal enthalten!
                return []
            # wort[vpos2] ist der zweite Vokal
            if vpos2 == 2 and wort[1] not in VOWELS:
                # Nach Einkonsonantenregel bleibt als erste Silbe nur ein einzelner Buchstabe,
                # z.B. o-ber. Das wollen wir nicht
                stpos = vpos2 + 1
                fertig = False
            if vpos2 == vpos1 + 1:
                # a sequence of two vowels, like German "ei" or "au", or English "ou" or "oi"
                if wort[vpos1:vpos2 +
                        1] in [u'äu', u'au', u'eu', u'ei', u'ie', u'ee']:
                    # Treat the sequence as if it was one vowel!
                    stpos = vpos2 + 1
                    fertig = False
                else:
                    return [
                        HyphenationPoint(vpos2, quality, 0, self.shy, 0, u"")
                    ] + self.schiebe(vpos2,
                                     self.dudentrennung(wort[vpos2:], quality))
        if wort[vpos2 - 3:vpos2] in [
                u'sch',
        ]:
            return [HyphenationPoint(
                vpos2 - 3, quality, 0, self.shy, 0, u"")] + self.schiebe(
                    vpos2 - 3, self.dudentrennung(wort[vpos2 - 3:], quality))
        elif ALTE_REGELN and wort[vpos2 - 2:vpos2] in [u'st']:
            return [HyphenationPoint(
                vpos2 - 2, quality, 0, self.shy, 0, u"")] + self.schiebe(
                    vpos2 - 2, self.dudentrennung(wort[vpos2 - 2:], quality))
        elif ALTE_REGELN and wort[vpos2 - 2:vpos2] in [u'ck']:
            return [
                HyphenationPoint(vpos2 - 1, quality, 1, u"k" + self.shy, 0,
                                 u"")
            ] + self.schiebe(vpos2 - 1,
                             self.dudentrennung(wort[vpos2 - 1:], quality))
        elif wort[vpos2 - 2:vpos2] in [u'ch', u'ck', u'ph']:
            return [HyphenationPoint(
                vpos2 - 2, quality, 0, self.shy, 0, u"")] + self.schiebe(
                    vpos2 - 2, self.dudentrennung(wort[vpos2 - 2:], quality))
        elif wort[vpos2 - 1] in VOWELS:
            return [HyphenationPoint(vpos2, quality, 0, self.shy, 0, u"")
                    ] + self.schiebe(vpos2,
                                     self.dudentrennung(wort[vpos2:], quality))
        else:
            return [HyphenationPoint(
                vpos2 - 1, quality, 0, self.shy, 0, u"")] + self.schiebe(
                    vpos2 - 1, self.dudentrennung(wort[vpos2 - 1:], quality))
Exemple #6
0
 def schiebe(self, offset, L):
     return [
         HyphenationPoint(h.indx + offset, h.quality, h.nl, h.sl, h.nr,
                          h.sr) for h in L
     ]