Geshi in Wiki einbauen und konfigurieren

Aus TobisWiki
Wechseln zu: Navigation, Suche

Inhaltsverzeichnis

Generic Syntax Highlighter (GESHI) in Wiki

Anwendungsgebiet

Ein Wiki (hier MediaWiki) ist etwas sehr geeignetes, um Inhalt für Benutzer zur Verfügung zu Stellen und diesen zu ermöglichen diesen Inhalt anzupassen. Damit man auch Quellcodes im Wiki vernünftig darstellen kann, hat mich eine Google-Suche zu Geshi geführt. Leider ist die Default Konfiguration für PHP nicht so das gelbe vom Ei. Da fehlen etliche Funktionen und auch die Sprachkonstrukte sind nicht vollständig enthalten. Ausserdem ist die Konfig ein bisschen tricky, aber wenn man weiss wo man was ändern muss, dann ist die Konfig unschlagbar flexibel. Man kann wirklich alles einstellen wie man will. Eine Anleitung zum einfachen Einbau gibt es hier.

Im folgenden soll es um die Erweiterung der PHP-Konfig gehen, damit alle Funktionen und Konstrukte vorhanden sind. Darum müssen wir uns im ersten Schritt die aktuelle Liste mit den Funktionen von http://www.php.net/quickref.php holen. Kopiert die Liste in die Zwischenablage und danach in ein Text File. Dieses File verarbeitet ihr danach mit einem kleinen PHP Script, damit ein String in der Form:

 
'function_name','fucntion_name','function_name'
 

entsteht. Dieser lässt sich dann in das PHP Config File von Geshi einbinden. (Geshi_in_Wiki_einbauen_und_konfigurieren#Funktionsliste_in_Array-Elemente_umwandeln)

Lizenz

Alle Codes unterstehen der GNU GPL

Verwendung

Konfigurationsparameter in php.php

Die beiden "Haupteinstellungsmöglichkeiten" in dieser Datei sind die beiden Array Keys STYLES und URLS. Bei STYLES ist das Unterelement KEYWORDS dafür verantwortlich die CSS Eigenschaften der einzelnen Gruppen (nummerische ID des Arrays) zu halten. KEYWORDS ist ein Array bei dem jedes Element einer Gruppe von oben entspricht

php.php als Zip File

 
'STYLES' => array(
        'KEYWORDS' => array(
            1 => 'color: black; font-weight:bold;',
            2 => 'color: blue; font-weight: bold;',
            3 => 'color: blue;',
            4 => 'color:green;',
            5 => 'color:black;'
            ),
        'COMMENTS' => array(
            1 => 'color: #808080; font-style: italic;',
            2 => 'color: #808080; font-style: italic;',
            'MULTI' => 'color: #808080; font-style: italic;'
            ),
        'ESCAPE_CHAR' => array(
            0 => 'color: #000099; font-weight: bold;'
            ),
        'BRACKETS' => array(
            0 => 'color: #66cc66;'
            ),
        'STRINGS' => array(
            0 => 'color: red;'
            ),
        'NUMBERS' => array(
            0 => 'color: #cc66cc;'
            ),
        'METHODS' => array(
            1 => 'color: #006600;',
            2 => 'color: #006600;'
            ),
        'SYMBOLS' => array(
            0 => 'color: #66cc66;'
            ),
        'REGEXPS' => array(
            0 => 'color: #0000ff;',
            1 => 'color: grey;'
            ),
        'SCRIPT' => array(
            0 => '',
            1 => '',
            2 => '',
            3 => ''
            )
        ),
    'URLS' => array(
        1 => 'http://php.net/{FNAME}',
        2 => '',
        //3 => 'http://php.net/manual/en/function.{FNAME}.php',
        3 => 'http://php.net/{FNAME}',
        4 => 'http://ch2.php.net/manual/de/language.constants.predefined.php',
        5 => 'http://ch2.php.net/manual/de/errorfunc.constants.php'
        ),
 

Wie gesagt ist das andere wichtige Element der Index URLS. Darin sind ebenfalls soviele Elemente enthalten wie man oben Gruppen hat. URLS enthält wie der Name schon sagt die URLs zum Manual und wie die Funktionsnamen verlinkt werden sollen. Soll keine Verlinkung stattfinden für eine bestimmte Gruppe, dann kann man einfach einen Leerstring angeben. {FNAME} ist eine Referenz auf den Treffer, den der RegExp gefunden hat. Das auskommentierte Beispiel bei 3 funzt leider nur bei Funktionen ohne _ im Namen. Das Problem ist, dass die Funktion for_bar() nur unter der Seite function.foo-bar.php gefunden wird. Um das zu korrigieren müsste man sich mit den regulären Ausdrücken von Geshi tiefer auseinandersetzen. Und was ich bis jetzt gesehen habe sind diese sehr komplex ;-) Aber man kann es umgehen indem man auf die Hauptseite/foo_bar.php linkt. So wird die Datei unter dem korrekten Namen der Funktion gefunden.

Code

Funktionsliste in Array-Elemente umwandeln

Nachdem die Funktionen in das Textfile eingefügt wurden, sollten diese in dieser Form stehen

funktion()
funktion()
...

Dieses File kann man dann mit folgendem Code in die obengeannte Form bringen

 
<?php
$data = file('/pfad/zum/File.txt');
foreach($data as $key=>$wert){
  if(empty($wert) || trim($wert) == ''){
    unset($data[$key]);
  }else{
    $data[$key] = "'".str_replace(array('(',')'),'',trim($wert))."'";
  }
}
$data = implode(",",$data);
echo $data;
?>
 

Elemente in Array einfügen

Diese Ausgabe dann wieder in die Zwischenabblage kopieren und folgende Datei in einem Editor öffnen (wiki/extension/geshi/geshi/php.php wobei wiki das Rootverzeichnis Eurer Wiki-Installation ist). Dort drin befindet sich die Config für das Syntax Highlightning in Form eines Arrays. Sucht nach dem Element mit dem Index 3. Dort steht etwas wie

 
3 => array(
'function','function','function','function',...
.......
)
 

Ersetzt alles zwischen ( und ) nach array mit den Daten aus der Zwischenablage. Damit habt ihr alle Funktionen in Geshi eingebaut.

Eigene Elemente in Array einbauen

Ihr könnt in dieses Array auch neue Elemente einbauen, die dann selber wieder verschiedene Elemente enthalten können. Hier am Beispiel der Error Konstanten, für die ich eine eigene Kategorie haben wollte. Dazu muss man in der php.php den letzten nummerischen Index suchen. In diesem Falle 3 (dort wo wir eben die Funktionen eingefügt haben). Direkt nach der schliessenden Klammer ) der Funktion array() muss zuerst ein Komma gesetzt werden. Dann sinnvollerweise ein Zeilenumbruch und dann das neu Array Element z.B.

 
'ziparchive_locatename','ziparchive_open','ziparchive_renameindex','ziparchive_renamename',
'ziparchive_setCommentName','ziparchive_setarchivecomment','ziparchive_setcommentindex',
'ziparchive_statindex','ziparchive_statname','ziparchive_unchangeall','ziparchive_unchangearchive',
'ziparchive_unchangeindex','ziparchive_unchangename','zlib_get_coding_type'
            ), //hier das Komma einfügen
     4=> array(
     'E_WARNING', 'E_PARSE', 'E_NOTICE',
            'E_CORE_ERROR', 'E_CORE_WARNING', 'E_COMPILE_ERROR', 'E_COMPILE_WARNING', 'E_USER_ERROR',
            'E_USER_WARNING', 'E_USER_NOTICE', 'E_ALL','E_STRICT'
            ) //das letzte Element darf KEIN Komma haben
 

Für Wiki alle PHP Funktionen

Mit dem folgenden Code könnt ihr Euch aus der Funktionsliste eine Wikiseite machen, die die Funktionen alphabetisch geordnet und ins Manual verlinkt ausgibt. Zum Sortieren habe ich usort() mit einer Callbackfunktion verwendet, da sort() zwischen Gross-und Kleinschreibung unterscheidet und erst die Funktionen von A-Z und erst dann die von a-z. Muss mal noch im Manual schauen ob es eine case-insensitive Sortierungsfunktion gibt. Aber der Callback war schneller geschrieben als die Suche um Manual ;-)

php_functions.txt als Zip File

 
<?php
function cmp($a,$b){
   return strcmp(strtolower($a),strtolower($b));
}
$data = str_replace("'",'',file_get_contents('./php_functions.txt'));
$data = preg_split('/,/',$data,-1,PREG_SPLIT_NO_EMPTY);
usort($data,"cmp");
$firstLetter = '';
foreach($data as $key=>$wert){
  if(empty($wert)){
    unset($data[$key]);
  }else{
    $wart = str_replace('_','-',$wert);
    if(strtolower($wert{0}) == $firstLetter){
      $data[$key] = '<strong>'.$wert.'
</strong> ([http://php.net/manual/de/function.'.$wart.'.php de] |  [http://php.net/manual/en/function.'.$wart.'.php en])';
    }else{
      $firstLetter = strtolower($wert{0});
      if($key > 0){
        $data[$key] = "</blockquote>\r\n=== ".strtoupper($wert{0})." === \r\n<blockquote><strong>".$wert.'
</strong> ([http://php.net/manual/de/function.'.$wart.'.php de] |  [http://php.net/manual/en/function.'.$wart.'.php en])';
      }else{
        $data[$key] = "=== ".strtoupper($wert{0})." === \r\n<blockquote><strong>".$wert.'
</strong> ([http://php.net/manual/de/function.'.$wart.'.php de] |  [http://php.net/manual/en/function.'.$wart.'.php en])';
      }
    }
  }
}
$data = implode("<br />\r\n",$data).'</blockquote>';
echo($data);
?>
 

Diese Ausgabe kopiert ihr in eine neue Wiki-Seite und speichert das Ganze ab. Et voilà...

mögliche Fehler

Im Element 1 des Arrays sind die Sprachkonstrukte untergebracht. Nur leider sind verschiedene Konstrukte (z.B. unset oder return) nun sowohl in der Funktionsliste (Element 3) als auch im ersten Element. Das bringt den Geshi Parser aus dem Tritt und erzeugt Fehler wie

unset">unset($data[$key]);

In diesen Fällen muss man die php.php Datei wieder öffnen und nach dem Funktions-oder Konstruktnamen suchen. Dieser darf nur einmal vorkommen im Array. Löscht also allfällige Elemente aus dem Array raus, die mehr als einmal vorkommen.

Downloads

Konfig File php.php für Geshi als zip File herunterladen
php_functions.txt als zip File herunterladen

Meine Werkzeuge