Benutzer:Ai/Daodejing Übersetzer

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen
Hinweis: Du darfst diese Seite editieren!
Ja, wirklich. Es ist schön, wenn jemand vorbeikommt und Fehler oder Links korrigiert und diese Seite verbessert. Sollten deine Änderungen aber der innehabenden Person dieser Benutzerseite nicht gefallen, sei bitte nicht traurig oder verärgert, wenn sie rückgängig gemacht werden.
Wikipedia ist ein Wiki, sei mutig!
<meta http-equiv="Content-Type" content="txt/html; charset=utf-8" />
<?php
/*****************************************
 *** Zeichenlexikon aus Datei einlesen ***
 *****************************************/
function ladeLexikon() {
  // Zeichenlexikon in $Lexikon und $Titel einlesen
  $fp = fopen("G:/wamp/www/Daodejing/Daodejing Zeichenlexikon.txt", "r");
  $LexikonQuelle = fread($fp, 10000000);
  fclose($fp);

  $LexikonQuelle = explode(chr(13).chr(10), $LexikonQuelle);
  $Lexikon = array();
  $Titel   = array();
  $TitelNr = 0;
  //$zaehler = 0;
  foreach($LexikonQuelle as $zeile) {
      if($zeile=='|}')  break;

    // Format: |<Wertung>||<Symbole>||<Pinyin>||<Einträge>
      if(!preg_match('~\|(.*)\|\|(.*)\|\|(.*)\|\|(.*)~ism', $zeile, $matches))  continue;
      if(!trim($matches[2]))  continue;

    // kompletten Eintrag merken
    $volltext = $matches[4];

    // Klammern entfernen
      while(preg_match('~(.*)\([^()]*\)(.*)~ism', $matches[4], $b1)) {
        $matches[4] = $b1[1].$b1[2];
      }
    // nach erstem Punkt alles abschneiden
       preg_match('~([^\.]*)\.~ism', $matches[4], $b1);
       $matches[4] = trim(!empty($b1[1]) ? $b1[1] : $matches[4]);

    // Einträge sind durch Strichpunkt getrennt
    $eintrag = explode(';', $matches[4]);

    // Zusatz (ungeklärt)
    $Zusatz = strpos($matches[1], '?') ? '  (ungeklärt)' : '';

    foreach($eintrag as $key => $bedeutung) {
      // Hauptbedeutung vor erstem Komma
      preg_match('~([^,]*)[,]~ism', $bedeutung, $Hauptbedeutung);
      $Hauptbedeutung = trim(!empty($Hauptbedeutung[1]) ? $Hauptbedeutung[1] : $bedeutung);

      // einige Ersetzungen einfacher Satzzeichen und Klammern
      $NeuerTitel = $matches[2]."  ".trim($matches[3]).$Zusatz."\n\n".$volltext;
      $Hauptbedeutung =
        str_replace('{',  '(',     str_replace('}',  ')',
        str_replace('<<', '&lt;',  str_replace('>>', '&gt;', $Hauptbedeutung))));
      $NeuerTitel =
        str_replace("\n", '&#10;', str_replace('  ', ' &nbsp;',
        str_replace('{',  '(',     str_replace('}', ')',
        str_replace('<<', '&lt;',  str_replace('>>', '&gt;',
        str_replace('; ', ";\n  ", str_replace('::',  ".",
        str_replace('#',  "\n  ",  preg_replace('~\. ~ism',  ".\n\n", trim($NeuerTitel), 1))))))))));
      $Titel[++$TitelNr] = $NeuerTitel;


      // $symbol ist der "key" des Lexikon-Eintrags
      if(preg_match('~^([A-Za-z]+):~ism', $Hauptbedeutung, $symbol)) {
        $Hauptbedeutung = trim(substr($Hauptbedeutung, strlen($symbol[0])));
        $symbol = $matches[2].$symbol[1];
      }else
        $symbol = $matches[2].($key ? $key+1 : '');



      // wenn $Hauptbedeutung kleingeschrieben, $symbol nur ein Schriftzeichen enthält
      // und keines der folgenden Nichtverben vorliegt
      if($Hauptbedeutung == strtolower($Hauptbedeutung)
            and !in_array(substr($Hauptbedeutung,0, 2), array('Ä', 'Ö', 'Ü'))
            and strlen($symbol) < 6
            and !in_array($Hauptbedeutung, array('mögen', 'vermögen',
            'wessen', 'unbesonnen', 'fern', 'verschieden', 'entstanden',
            'selten', 'hinten', 'geschätzten', 'unten', 'inmitten',
            'gelungen', 'oben', 'emporgehoben', 'trocken', 'verborgen',
            'unvollkommen', 'gelassen', 'hingegen', 'verglichen', 'verdorben'))) {


        $VerbBeugen = false;

        if(($Hauptbedeutung=='bevorzugen' or !strpos($Hauptbedeutung, 'zu'))
            and !strpos($Hauptbedeutung, '/')
            and substr($Hauptbedeutung, 0, 3)!='zu ')
        // Wortende modifizieren
        foreach( array(
          'gebären'=> 'gebiert',// gebären
          'wachsen'=> 'wächst', // erwachsen
          'nehmen' => 'nimmt',  // einnehmen, zunehmen
          'halten' => 'hält',   //  6x
          'werden' => 'wird',   // werden
          'können' => 'kann',   // können
          'knien'  => 'kniet',  // knien
          'sehen'  => 'sieht',  // sehen
          'geben'  => 'gibt',   // geben, umgeben, vergeben
          'haben'  => 'hat',    // satthaben, haben
          'essen'  => 'ißt',    // vermessen
          'echen'  => 'icht',   // zerbrechen, entsprechen, sprechen
          'effen'  => 'ifft',   // übertreffen
          'elfen'  => 'ilft',   // helfen
          'erfen'  => 'irft',   // unterwerfen, verwerfen
          'erben'  => 'irbt',   // sterben, verderben
          'chnen'  => 'chnet',  // zeichnen, bezeichnen
          'dnen'   => 'dnet',   // ordnen
          'fnen'   => 'fnet',   // öffnen
          'gnen'   => 'gnet',   // begegnen
          'eten'   => 'itt',    // eintreten
          'aten'   => 'ät',     // braten
          'ssen'   => 'ßt',     // umfassen, veranlassen
          'eln'    => 'elt',    // entwickeln, handeln
          'ten'    => 'tet',    // 20x
          'den'    => 'det',    // 17x
          'rn'     => 'rt',     // 11x
          'en'     => 't',      // 109x
        ) as $key2 => $value ) {
          if($key2==substr($Hauptbedeutung, -strlen($key2))) {
            $HauptT = substr_replace($Hauptbedeutung, $value, -strlen($key2));
            $HauptE = substr_replace($Hauptbedeutung, 'e', -1-(substr($Hauptbedeutung, -2) == 'en'));
            if(substr($HauptE, -3) == 'ele')
              $HauptE = substr_replace($HauptE, 'le', -3);  // handLE
            $VerbBeugen = true;
            break;
          }
        }

        // Lexikon-Nebeneinträge mit gebeugtem Verb
        if($VerbBeugen) {
          $Lexikon[$symbol.'t'] = array(
            'pinyin'    => trim($matches[3]),
            'bedeutung' => '<span title="'.$TitelNr.'">'."\n".$HauptT.'</span>', //$HauptT,//
          );
          $Lexikon[$symbol.'E'] = array(
            'pinyin'    => trim($matches[3]),
            'bedeutung' => '<span title="'.$TitelNr.'">'."\n".$HauptE.'</span>', //$HauptE,//
          );
        }
      }

      // Lexikon-Haupteintrag
      $Lexikon[$symbol] = array(
        'pinyin'    => trim($matches[3]),
        'bedeutung' => '<span title="'.$TitelNr.'">'."\n".$Hauptbedeutung.'</span>', //$Hauptbedeutung,//
      );
      //** nur für rules.php **
      if(!$key)  $Lexikon[$symbol]['volltext'] = $volltext;
    }
  }

  uksort($Lexikon, 'sortiereLexikon');
  return array($Lexikon, $Titel);
}


/**********************************************
 *** Originaltext aus Datei auslesen        ***
 *** und gewünschte Abschnitte ausschneiden ***
 **********************************************/
function ladeWangBi($Kapitel=null) {
  // chinesisches Original einlesen
  $Datei = fopen("G:/wamp/www/Daodejing/Wang Bi - Ansgar Gerstner.txt", "r");
  $Original = fread($Datei, 10000000);
  fclose($Datei);

  // bei leerer Kapitelwahl Original zurückgeben
  if(empty($Kapitel))
    return $Original;

  // Kapitel ausschneiden
  $NummerierteAbschnitte = explode("===", $Original);
  // und aneinanderhängen
  $GewuenschteAbschnitte = array( chr(13).chr(10) );

  $speichern = false;
  foreach($NummerierteAbschnitte as $wert)
  {
    if(in_array($wert, $Kapitel))  { $GewuenschteAbschnitte[] = $wert;  $speichern = true;  }
    elseif($speichern)             { $GewuenschteAbschnitte[] = $wert;  $speichern = false; }
  }
  return implode("====", $GewuenschteAbschnitte);
}


/******************************
 *** Übersetzung generieren ***
 ******************************/
function uebersetze($Chinesisch, $Lexikon) {
  list($Lexikon, $Titel) = $Lexikon;
  // Formatierung
  $Chinesisch   = explode(chr(13).chr(10), $Chinesisch);
  $Uebersetzung = $Pinyin = $Original = '';

  foreach($Chinesisch as $Zeile)
  {
    // erste Zeile ignorieren
    if(empty($IgnoriereZeileEins))  { $IgnoriereZeileEins = true; continue; }
    // falls Zeile Kapitelnummer enthält
    if(preg_match('~=+ (.*) =+~ism', $Zeile, $matches)) {
          $Original     .= "=== $matches[1] ===\n";
          $Pinyin       .= "=== $matches[1] ===\n";
        $Uebersetzung .= "=== $matches[1] ===\n";
        continue;
      };
    // falls Zeile mit wiki-table-code beginnt
      if(strlen($Zeile)<3 or preg_match('~^{{~ism', $Zeile))  continue;

    //falls Zeile chinesisch ist
    $Zeile = trim($Zeile);

    // entferne führendes Bewertungszeichen
    if(in_array($Zeile{0}, array('#', '-', '=', '+')))  {$Zeile = substr($Zeile, 1);}

    $Orgi = '';
    $pin  = '';
    for($i=0; $i<strlen($Zeile); $i+=1) {
      $char = mb_strcut($Zeile, $i, 1);
      if($char=='|' and mb_strcut($Zeile, $i, 3)=='|||') {
        $Orgi .= "<br>\n&nbsp; &nbsp; &nbsp; &nbsp; ";
        $pin  .= "<br>\n&nbsp; &nbsp; &nbsp; ";
      }
      if(ord($char)<200)  continue;
      $char = mb_strcut($Zeile, $i, 3); $i+=2;

      $Orgi .= $char;
      if($char != '。')
        $pin .= empty($Lexikon[$char]['pinyin']) ? ' *' : ' '.$Lexikon[$char]['pinyin'];
    }
    $pin = trim(preg_replace('~bù( [^ ]*(à|è|ì|ò|ù))~ism', 'bú$1', $pin));

    //falls Zeile chinesisch beginnt
    $zirkuliert = zirkuliere($Zeile);

    $Original     .= "$Orgi<br>\n";
    $Pinyin       .= "$pin<br>\n";
    $Uebersetzung .= "$zirkuliert<br>\n";

    str_ireplace(array('<br>', '</br>', '||'), '*', str_replace('|||', '*', $zirkuliert), $ZahlDerZeilenumbrueche);
    $Original .= str_repeat("<br>\n", $ZahlDerZeilenumbrueche);
    $Pinyin   .= str_repeat("<br>\n", $ZahlDerZeilenumbrueche);
  }


  /*** alle Ersetzungsregeln anwenden ***/
  foreach($Lexikon as $key=>$value)
    $Uebersetzung = str_replace($key, ' '.$value['bedeutung'], $Uebersetzung);


  /* Groß-/Kleinschreibung mittels // und \\ */
  for($i=0; $i<2; $i++) {
    while($pos = strpos($Uebersetzung, '//')) {
      $pos2 = $pos + 2;
      $InTag = false;
      while((ord($z=$Uebersetzung{$pos2})!=195 and ($z<'A' or ($z>'Z' and $z<'a') or $z>'z')) or $InTag) {
        $pos2++;
        if($z=='<') $InTag = true;
        if($z=='>') $InTag = false;
      }
      if(ord($Uebersetzung{$pos2})==195) {  // erstes Byte von Ä, Ö, Ü, ä, ö oder ü, dann zweites Byte + oder - 32 oder unverändert
        $Uebersetzung = substr_replace($Uebersetzung, $i ? chr(ord($Uebersetzung{++$pos2}) | 32) : chr(ord($Uebersetzung{++$pos2}) & 223), $pos2, 1);
      }else{  // sonst is klar
        $Uebersetzung = substr_replace($Uebersetzung, $i ? strtolower($Uebersetzung{$pos2})      : strtoupper($Uebersetzung{$pos2}),       $pos2, 1);
      }
      $Uebersetzung = substr_replace($Uebersetzung, '', $pos, 2);
    }
    // für den zweiten Durchlauf alle \\ durch // ersetzen
    if(!$i)  $Uebersetzung = str_replace('\\\\', '//', $Uebersetzung);
  }

  /*** letzte Formatierungen ***/
  /* Zeilenumbrüche */
  $Uebersetzung = str_replace(array("|||", "||"), "<br>\n&nbsp; &nbsp; &nbsp; &nbsp; ", $Uebersetzung);
  /* Leerzeichen eliminieren */
  $Uebersetzung = str_replace("_ ", "", $Uebersetzung);
  // Verbindungen zweier Wörter (54x); notwendig geworden durch den Zeilenumbruch in jedem <span>
  $Uebersetzung = preg_replace('~_(<span[^<>]+>)\n~ism', '$1', $Uebersetzung, -1, $count);

  /* Tool-Tip-Tags auf die ganzen Wörter ausweiten */
  $Uebersetzung = preg_replace('~(</span>)(([A-Za-z]|Ä|Ö|Ü|ä|ö|ü|ß)+)( |<|。)~ism',       '$2$1$4',  $Uebersetzung);
  $Uebersetzung = preg_replace('~(\s)(([A-Za-z]|Ä|Ö|Ü|ä|ö|ü|ß|")+)(<span[^<>]+>\s)~ism', '$1$4$2', $Uebersetzung);

  /* Tool-Tips integrieren */
  foreach($Titel as $Index=>$Wert)
    $Uebersetzung = str_replace('"'.$Index.'"', '"'.$Wert.'"', $Uebersetzung);

  /* hide-Tags in spans umwandeln */
  $Uebersetzung = str_replace('<hide>',  '<span style="color:white; background:white; padding-bottom:1px;">', $Uebersetzung);
  $Uebersetzung = str_replace('</hide>', '</span>', $Uebersetzung);



  /* manuell zu korrigierende Pinyin-Abweichungen */
  $Pinyin = str_replace("jiāng jūn",    "jiàng jūn",    $Pinyin);  // 將  jiàng     General     (31)
  $Pinyin = str_replace("wàn chéng",    "wàn shèng",    $Pinyin);  // 乘  shèng     Streitwagen (26)
  $Pinyin = str_replace("shí mǔ",       "sì mǔ",        $Pinyin);  // 食  sì        nähren      (20)
  $Pinyin = str_replace("zhōng cháo",   "zhōng zhāo",   $Pinyin);  // 朝  zhāo      Morgen      (23)
  $Pinyin = str_replace("zhàng fú",     "zhàng fū",     $Pinyin);  // 丈夫 zhàng fū  Mann        (38)
  $Pinyin = str_replace("qiáng wéi",    "qiǎng wéi",    $Pinyin);  // 強  qiǎng     angestrengt (15, 25)
  $Pinyin = str_replace("wù qiáng",     "wù qiǎng",     $Pinyin);  // 強  qiǎng     erzwingen   (30)
  $Pinyin = str_replace("cháng ér",     "zhǎng ér",     $Pinyin);  // 長  zhǎng     leiten      (10, 51)
  $Pinyin = str_replace("gù cháng<",    "gù zhǎng<",    $Pinyin);  // 長  zhǎng     leiten      (22)
  $Pinyin = str_replace("bù cháng",     "bù zhǎng",     $Pinyin);  // 長  zhǎng     leiten      (24)
  $Pinyin = str_replace("guān cháng",   "guān zhǎng",   $Pinyin);  // 長  zhǎng     leiten      (28)
  $Pinyin = str_replace("cháng zhī",    "zhǎng zhī",    $Pinyin);  // 長  zhǎng     leiten      (28)
  $Pinyin = str_replace("nǎi cháng",    "nǎi zhǎng",    $Pinyin);  // 長  zhǎng     leiten      (54)
  $Pinyin = str_replace("qì cháng",     "qì zhǎng",     $Pinyin);  // 長  zhǎng     leiten      (67)

  return array($Original, $Pinyin, $Uebersetzung);
}


/******************************************************************
 *** erste Verarbeitungsstufe: geschweifte Klammern zirkulieren ***
 ******************************************************************/
function zirkuliere($Zeile) {
  // solange geschweifte Klammern vorhanden sind
  // (die ihrerseits keine geschweiften Klammern enthalten)
  while(preg_match("~^(.*){([^{}]*)}(.*)$~ism", $Zeile, $Treffer))
  {                 /*  1 {    2   }  3 */
    $VorDerKlammer  = $Treffer[1];
    $InDerKlammer   = $Treffer[2];
    $NachDerKlammer = $Treffer[3];

    // letztes chinesische Schriftzeichen in der Klammer finden
    $pLetztesZeichen = strlen( $InDerKlammer ) - 1;
    while( $pLetztesZeichen and (128 > ord( $InDerKlammer{$pLetztesZeichen} )) )
      $pLetztesZeichen--;
    $pLetztesZeichen -= 2;

    // ab diesem abtrennen
    $Ende   = substr($InDerKlammer, $pLetztesZeichen);
    $Anfang = substr($InDerKlammer, 0, $pLetztesZeichen);

    // und vor den Anfang setzen
    $Zeile = $VorDerKlammer.$Ende.$Anfang.$NachDerKlammer;
  }
  return $Zeile;
}


/*******************************************
 *** Callback-Funktion zum Sortieren der ***
 *** Lexikoneinträge nach Indexlänge     ***
 *******************************************/
function sortiereLexikon($Index1, $Index2) {
  if(strlen($Index1) == strlen($Index2))  return $Index1 > $Index2;
  return strlen($Index1) < strlen($Index2);
}


/*********************
 *** HAUPTPROGRAMM ***
 *********************/
$Abschnitte = array(
 1, 2, 3, 4,  6, 8,12,16, 17,24,29,34, 37,47,
48,49,51,56, 61,62,66,75, 81,25,32,76, 68,        /* erstes Drittel fertig */
 5, 7,11,33, 40,43,23,71, 60, 9,22,44, 52,59,
63,70,79,38, 57,64,65,72, 50,67,73,77, 78,        /* zweites Drittel fertig */
18,19,35,36, 45,46,69,74, 10,13,
28,26,30,80, 54,53,58,41, 55,27,
14,31,15,42, 39,21,20,                            /* drittes Drittel fertig */
);

//$Abschnitte = array_diff( array_keys( array_fill(1, 81, 1) ), $Abschnitte );  /* invertiert die Auswahl */

/***************************************
 * Uebersetung generieren und ausgeben *
 ***************************************/
list($OriginalAuszug, $Pinyin, $Uebersetzung) = uebersetze( ladeWangBi($Abschnitte), ladeLexikon() );


/*** zur Ausgabe im Browser ***
$OriginalAuszug = preg_replace('~=== ([0-9]+) ===~ism', '<h3>Abschnitt $1</h3>',        $OriginalAuszug);
$Pinyin         = preg_replace('~=== ([0-9]+) ===~ism', '<h3>&nbsp; <!-- $1 --> </h3>', $Pinyin);
$Uebersetzung   = preg_replace('~=== ([0-9]+) ===~ism', '<h3>&nbsp; <!-- $1 --> </h3>', $Uebersetzung);
echo "
<div style='float:left;line-height:1.25em'>".            $OriginalAuszug."</div>\n\n
<div style='float:left;line-height:1.25em'>".            $Pinyin        ."</div>\n\n
<div style='float:left;line-height:1.25em; color:#408'>".$Uebersetzung  ."</div>\n\n";
exit;/**/


/*** Ausgabe im Wiki-Format ***/

// führende Leerzeichen entfernen
$Uebersetzung = preg_replace("~\n +([^ ])~ism", "\n$1", $Uebersetzung);

$splitO = explode("===", $OriginalAuszug);
$splitP = explode("===", $Pinyin);
$splitU = explode("===", $Uebersetzung);

$wikiText = '__KEIN_INHALTSVERZEICHNIS__
{|cellspacing="0" cellpadding="0" style="text-align: right; font-size: small;"
|-
';
for($i=1; $i<=81; $i++) {
  $wikiText .= "|[[#Abschnitt $i|&nbsp;$i&nbsp;]]\n";
  if($i<81 and !($i%9))  $wikiText .= "|-\n";
}
$wikiText .= "|}\n\n";

foreach($splitO as $key=>$value) {
  if(empty($IgnoriereZeileEins))  { $IgnoriereZeileEins = true; continue; }
  if(is_numeric(trim($value))) {
    $wikiText .= "=== Abschnitt$value===\n";
    continue;
  }
  $wikiText .=
"{|
|-
|style='width:13em'|
$value
|style='width:20em'|
$splitP[$key]
|style='color:#408'|
$splitU[$key]
|}

";
}

echo $wikiText;
?>