Seite 2 von 3

Verfasst: 03.05.2009 19:10
von Thorsten1867
Little John hat geschrieben:Das selbe Problem z.B. bei
Holz - ti - sch
Aber komisch ist -- zumindest für mich, der ich mich mit dem zu Grunde liegenden Algorithmus nicht beschäftigt habe -- dass
Tisch
richtigerweise nicht getrennt wird.
Die Pattern stammen nicht von mir, sondern gehören zum Algorithmus.

Zusammengesetzte Wörter sollen teilweise Schwierigkeiten machen. Man muss dafür wohl eine Ausnahmeliste erstellen.

[Edit]Problem gefunden! Wortende wurde nicht als solches erkannt.[/Edit]

Verfasst: 04.05.2009 18:23
von Thorsten1867
Optimierter und fehlerbereinigter Code:

Code: Alles auswählen

;/ Silbentrennung
;/ Algorithmus von Frankling Mark Liang (1983)
;/ basierend "hyphenator für HTML" (Mathias Nater, Zürich)
;/ Mai 2009 Thorsten Hoeppner (Thorsten1867)


Structure HyphenStructure
  chars.s
  pattern.s
EndStructure

Global NewList HyphPattern.HyphenStructure()

Procedure LoadPattern(PatternFile.s)
  ClearList(HyphPattern())
  If ReadFile(0, PatternFile.s)
    While Eof(0) = 0 
      pattern$ = Trim(ReadString(0,#PB_UTF8))
      AddElement(HyphPattern())
      HyphPattern()\chars = StringField(pattern$,1,":")
      HyphPattern()\pattern = StringField(pattern$,2,":")
    Wend 
    CloseFile(0)
  Else
    MessageRequester("Lade Trennungsmuster", "Datei konnte nicht eingelesen werden.", 0)
  EndIf
EndProcedure

Procedure.s InsertString(string.s, idx.b, chars.s)
  If idx > 1
    result.s = Left(string, idx-1)+chars+Mid(string, idx)
  ElseIf idx >= Len(string)
    result.s = string + chars
  Else
    result.s = chars + string
  EndIf
  ProcedureReturn result
EndProcedure

Procedure.s HyphenateWord(wort.s)
  Define.b WLen, WIdx
  Define.s Char, LWort
  
  wort = "_"+wort+"_"
  LWort = LCase(wort)
  WLen = Len(wort)
  Dim Hypos.s(WLen)
  
  ForEach HyphPattern() ; Pattern auswerten
    WortIdx = FindString(LWort, HyphPattern()\chars, 1)
    If WortIdx
      digits = 1
      For i=1 To Len(HyphPattern()\pattern)
        Char.s = Mid(HyphPattern()\pattern, i, 1)
        If Asc(Char) >= 48 And Asc(Char) <= 57 ; Ist Zahl (0-9)
          If i = 1
            z = WortIdx
          Else
            z = WortIdx + i - digits
          EndIf
          If Not Hypos(z) Or Hypos(z) < Char ; kleinere Zahl überschreiben
            Hypos(z) = Char
          EndIf
          digits + 1
        EndIf
      Next
      Debug "Pattern: "+HyphPattern()\pattern+" ("+Str(WortIdx)+")"
    EndIf
  Next

  inserted.b = 0 ; Trennmuster erzeugen
  For i = 3 To WLen-2
    If Val(Hypos(i))
      wort = InsertString(wort, i + inserted, Hypos(i))
      inserted + 1
    EndIf
  Next  ;}
  
  wort.s = RemoveString(wort, "_") ; Wortanfang/-ende entfernen
  Debug "Trennmuster: "+wort
  For i = 1 To 9 ; Trennstellen ermitteln (ungerade Zahlen)
    If (i % 2) ; Trennstelle
      wort = ReplaceString(wort, Str(i), "|")
    Else ; keine Trennstelle
      wort = RemoveString(wort, Str(i))
    EndIf
  Next
  ProcedureReturn wort
EndProcedure

LoadPattern("HyphenPattern.de")

wort$ =  InputRequester("Silbentrennung", "Wort eingeben:", "")
result$ = HyphenateWord(wort$)
MessageRequester("Silbentrennung", ReplaceString(result$, "|", " - "), #MB_OK)
Sourecode + Hyphenation Patterns

Verfasst: 04.05.2009 20:05
von Kiffi
Thorsten1867 hat geschrieben:Optimierter und fehlerbereinigter Code:
Super, vielen Dank! :allright:

Grüße ... Kiffi

Verfasst: 05.05.2009 16:29
von Andesdaf
ich schließe mich Kiffi an :allright:

Danke!

Verfasst: 05.05.2009 17:39
von Bagalut
Andesdaf hat geschrieben:ich schließe mich Kiffi an :allright:
Ich auch! Danke! :allright:

Verfasst: 05.05.2009 17:41
von Little John
Ich schließe mich Andesdaf an. ;-)
Beeindruckend!

Gruß, Little John

Verfasst: 05.05.2009 19:47
von c4s
Danke!

Aber was ist z.B. hiermit:
fußballspieltorwart -> fuß - ball - spieltor - wart
"Spiel" und "Tor" müssten doch ebenfalls getrennt werden?!

Verfasst: 05.05.2009 20:36
von Little John
c4s hat geschrieben:Danke!

Aber was ist z.B. hiermit:
fußballspieltorwart -> fuß - ball - spieltor - wart
"Spiel" und "Tor" müssten doch ebenfalls getrennt werden?!
Das Wort
fußballspieltorwart
habe ich weder je gehört noch im Duden gefunden. Erwartest Du, dass das Programm jedes ausgedachte Wort trennen kann?

Die Wörter
Fußballspiel
Fußballspieler
Fußballspielerin
Fußballtor
Fußballtorwart
werden jedenfalls alle korrekt getrennt.

Gruß, Little John

Verfasst: 05.05.2009 21:21
von c4s
So ganz zufrieden bin ich dennoch nicht:
Heizöl -> Hei - zöl
Schifffahrt -> Schif - f- fahrt
Aber hast ja recht ;)

Verfasst: 05.05.2009 21:47
von Thorsten1867
Zusammengesetzte Namenwörter können evtl. Probleme machen, da es sich um einen Algorithmus und nicht um eine Wörterliste handelt.
Für solche Fälle muss eine Ausnahmeliste angelegt werden.

Ich empfehle zu dem Thema Trennproblematik die Artikeln zur Silbentrennung (siehe Beitrag weiter oben) zu lesen.

Der "Schifffahrt" und der "Balletttänzerin" kann man abhelfen. Füge folgende Pattern in die Pattern-Datei ein:
fff:f6f9f
ttt:t6t9t
[Edit]In der neuen Patterndatei schon enthalten.[/Edit]