- <html>
- <head>
- <link href="/css/html4strict.css" rel="stylesheet" type="text/css" media="screen" />
- <title>Geshi</title>
- </head>
- <body>
- <p>
- <?php
- define('ROOT_DIR', dirname(__FILE__));
- set_include_path(get_include_path() . PATH_SEPARATOR . ROOT_DIR . DIRECTORY_SEPARATOR . 'library');
- set_include_path(get_include_path() . PATH_SEPARATOR . ROOT_DIR . DIRECTORY_SEPARATOR . 'includes');
- require_once 'prettyfile.php';
- echo pretty_file('geshitest.php', 'html4strict');
- ?>
- </p>
- </body>
- </html>
Coloration syntaxique des fichiers sources
Bien présenter des fichiers sources en les colorisant les rend plus lisibles et plus attractifs. Rien de plus facile avec GeSHi et un peu de code en PHP.
Téléchargez GeSHi - Generic Syntax Highlighter. Ouvrez l'archive geshi-*.bz2.
Organisez le contenu de votre site en créant à la racine du site les dossiers includes pour les fichiers inclus et library pour votre propre code. Copiez le répertoire geshi et le fichier geshi.php de l'archive dans /includes.
- /
- includes
- geshi
- geshi.php
- library
- prettyfile.php
- includes
Copiez le code suivant dans un fichier appelé prettyfile.php dans /library.
prettyfile.php définit deux fonctions : read_file
et pretty_file
.
read_file
lit tout un fichier, ou une partie d'un fichier, dans une chaîne de caractères.
pretty_file
retourne tout le contenu d'un fichier, ou d'une partie d'un fichier, mis en valeur pour un langage informatique donné.
- require_once 'geshi.php';
Le code commence par charger les fonctions de geshi.php. NOTE : Configurez votre site pour que les répertoires /includes et /library soient listés dans le chemin d'inclusion de PHP. Ajoutez les lignes suivantes au début de votre code à la racine du site :
define('ROOT_DIR', dirname(__FILE__));
set_include_path(get_include_path() . PATH_SEPARATOR . ROOT_DIR . DIRECTORY_SEPARATOR . 'library');
set_include_path(get_include_path() . PATH_SEPARATOR . ROOT_DIR . DIRECTORY_SEPARATOR . 'includes');
read_file
- function read_file($file, $startline=0, $endline=0) {
- if ($startline or $endline) {
- $lines=@file($file);
- if (false === $lines) {
- return false;
- }
- $offset=$startline ? $startline-1 : 0;
- if ($endline) {
- $length=$startline ? $endline - $startline + 1 : $endline;
- $lines = array_slice($lines, $offset, $length);
- }
- else {
- $lines = array_slice($lines, $offset);
- }
- $s=implode('', $lines);
- }
- else {
- $s=@file_get_contents($file);
- if (false === $s) {
- return false;
- }
- }
- $s=rtrim($s);
- return $s;
- }
Si les deux paramètres $startline
et $endline
valent 0, on lit tout le fichier avec file_get_contents
.
Pour extraire une partie du fichier, on le lit avec file
qui retourne toutes les lignes dans un tableau. Chaque ligne dans $lines
inclut le caractère de fin de ligne, sauf éventuellement la dernière.
$lines
est réduit avec array_slice
à la portion du fichier voulu.
Si $startline
vaut 0, les $endline
premières lignes sont extraites.
Si $endline
vaut 0, toutes les lignes de $startline
à la fin du fichier sont extraites.
Si $startline
et $endline
sont différents de 0, les lignes entre $startline
et $endline
sont extraites.
Le tableau obtenu est changé en une chaîne de caractères avec implode
.
Enfin, les lignes vides en fin de texte sont supprimées.
read_file
retourne les lignes lues à partir de $file
dans une chaîne de caractères ou false
en cas d'erreur.
pretty_file
- function pretty_file($file, $language, $startline=0, $endline=0) {
- $s=read_file($file, $startline, $endline);
- if (!$s) {
- return false;
- }
- if (!$language) {
- return $s;
- }
- $output = false;
- switch ($language) {
- case 'plain':
- $s = preg_replace("/\]\=\>\n(\s+)/m", "] => ", $s);
- $s = htmlentities($s, ENT_COMPAT, 'UTF-8');
- $output = '<pre class="plain">' . PHP_EOL . $s . '</pre>' . PHP_EOL;
- break;
- default:
- $geshi = new GeSHi($s, $language);
- $geshi->enable_classes(true);
- $geshi->set_header_type(GESHI_HEADER_DIV);
- $geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS);
- $geshi->start_line_numbers_at($startline > 0 ? $startline : 1);
- $geshi->enable_keyword_links(false);
- $geshi->set_tab_width(4);
- // echo '<pre>' . PHP_EOL .$geshi->get_stylesheet( ). '</pre>' . PHP_EOL;
- $output = $geshi->parse_code();
- if ($geshi->error()) {
- return false;
- }
- }
- return $output;
- }
pretty_file
commence par appeler read_line
pour lire $file
de $startline
à $endline
. En cas d'erreur, elle retourne false
.
Si $language
n'est pas spécifié, le contenu de $file
est retourné sans formatage. NOTE : Évitez de lire un fichier dont le contenu peut être interprété par un navigateur.
Si $language
vaut 'plain'
, le contenu de $file
est retourné dans un bloc <pre>
avec l'attribut class
à la valeur plain pour le CSS.
L'indentation et les renvois à la ligne sont nettoyés et les entités HTML sont récrites avec htmlentities
. Remarquez que le texte est censé avoir été encodé en UTF-8.
Toute autre valeur du paramètre $language
fait appel à GeSHi.
$geshi
est initialisé avec les lignes à formater et le nom du langage informatique.
Ensuite, avant d'appeler parse_code
, l'objet est configuré de façon à obtenir le fichier en sortie le plus petit sans aucun code CSS.
pretty_file
retourne $output
ou false
en cas d'erreur.
Écrivez un petit document qui testera pretty_file
en se colorisant lui-même. Enregistrez le code suivant dans un fichier appelé geshitest.php dans le dossier racine du site :
- <html>
- <head>
- <link href="/css/html4strict.css" rel="stylesheet" type="text/css" media="screen" />
- <title>Geshi</title>
- </head>
- <body>
- <p>
- <?php
- define('ROOT_DIR', dirname(__FILE__));
- set_include_path(get_include_path() . PATH_SEPARATOR . ROOT_DIR . DIRECTORY_SEPARATOR . 'library');
- set_include_path(get_include_path() . PATH_SEPARATOR . ROOT_DIR . DIRECTORY_SEPARATOR . 'includes');
- require_once 'prettyfile.php';
- echo pretty_file('geshitest.php', 'html4strict');
- ?>
- </p>
- </body>
- </html>
Si on accède au document avec un navigateur, on n'obtient pas exactement le résultat attendu.
Remarquez la balise <link>
qui tente d'inclure un fichier de feuille de style nommé /css/html4strict.css. Il ne reste plus qu'à construire ce fichier.
Style
Le HTML retourné par pretty_file
ne contient pas du tout de CSS. Pour correctement appliquer le style de votre page, demandez à GeSHi de générer la feuille de style et enregistrez-la dans un fichier à part que vous inclurez dans le document.
pretty_file
peut le faire. Il suffit de décommenter la ligne qui affiche la feuille de style.
- // echo '<pre>' . PHP_EOL .$geshi->get_stylesheet( ). '</pre>' . PHP_EOL;
Rechargez geshitest.php dans votre navigateur. Le source de la feuille de style est affiché au début.
/**
* GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann
* (http://qbnz.com/highlighter/ and http://geshi.org/)
*/
.html4strict {font-family:"Courier New", Courier, monospace; font-size:10pt;}
.html4strict .de1, .html4strict .de2 {margin:0; padding:0; background:none; vertical-align:top;}
.html4strict .imp {font-weight: bold; color: red;}
.html4strict li, .html4strict .li1 {font-weight: normal; vertical-align:top;}
.html4strict .ln {width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}
.html4strict .kw2 {color: #000000; font-weight: bold;}
.html4strict .kw3 {color: #000066;}
.html4strict .es0 {color: #000099; font-weight: bold;}
.html4strict .br0 {color: #66cc66;}
.html4strict .sy0 {color: #66cc66;}
.html4strict .st0 {color: #ff0000;}
.html4strict .nu0 {color: #cc66cc;}
.html4strict .sc-1 {color: #808080; font-style: italic;}
.html4strict .sc0 {color: #00bbdd;}
.html4strict .sc1 {color: #ddbb00;}
.html4strict .sc2 {color: #009900;}
.html4strict span.xtra { display:block; }
1. <html>
2. <head>
3. <link href="/css/html4strict.css" rel="stylesheet" type="text/css" media="screen" />
4. <title>Geshi</title>
5. </head>
6. <body>
7. <p>
8. <?php
9. define('ROOT_DIR', dirname(__FILE__));
10.
11. set_include_path(get_include_path() . PATH_SEPARATOR . ROOT_DIR . DIRECTORY_SEPARATOR . 'library');
12. set_include_path(get_include_path() . PATH_SEPARATOR . ROOT_DIR . DIRECTORY_SEPARATOR . 'includes');
13.
14. require_once 'prettyfile.php';
15.
16. echo pretty_file('geshiexample.php', 'html4strict');
17. ?>
18. </p>
19. </body>
20. </html>
La sortie peut différer selon la version de GeSHi qui est installée. N'hésitez pas à changer quelques propriétés comme font-family
ou font-size
.
Copiez le CSS et collez-le dans un fichier nommé d'après le langage du code source, html4strict.css dans l'exemple. Sauvegardez le fichier dans un dossier css sous la racine de votre site.
- /
- includes
- geshi
- geshi.php
- library
- prettyfile.php
- css
- html4strict.css
- includes
Après que vous avez généré et sauvegardé tous les fichiers CSS pour tous les différents langages que vous publiez, remettez en commentaire la ligne de code dans prettyfile.php
qui affiche la feuille de style.
Maintenant, si on recharge le document, le fichier CSS est bien trouvé et le code source a la bonne apparence.
- <html>
- <head>
- <link href="/css/html4strict.css" rel="stylesheet" type="text/css" media="screen" />
- <title>Geshi</title>
- </head>
- <body>
- <p>
- <?php
- define('ROOT_DIR', dirname(__FILE__));
- set_include_path(get_include_path() . PATH_SEPARATOR . ROOT_DIR . DIRECTORY_SEPARATOR . 'library');
- set_include_path(get_include_path() . PATH_SEPARATOR . ROOT_DIR . DIRECTORY_SEPARATOR . 'includes');
- require_once 'prettyfile.php';
- echo pretty_file('geshitest.php', 'html4strict');
- ?>
- </p>
- </body>
- </html>
Application
La fonction d'iZend qui formate les commentaires à l'aide de GeSHi :
- require_once 'geshi.php';
- function bbcode($s) {
- static $bbcode = array(
- '#\[br\]#is' => '<br />',
- // '#\[(h[1-6])\](.+?)\[/\1\]#is' => '<\1>\2</\1>',
- '#\[(b|i|u|s)\](.+?)\[/\1\]#is' => '<\1>\2</\1>',
- '#\[(p|pre)\](.+?)\[/\1\]#is' => '<\1>\2</\1>',
- '#\[quote\](.+?)\[/quote\]#is' => '<blockquote>\1</blockquote>',
- '#\[(url)\=(.+?)\](.*?)\[/\1\]#ise' => "filter_var('\\2', FILTER_VALIDATE_URL) ? '<a href=\"\\2\" target=\"_blank\">\\3</a>' : '\\0'",
- '#\[(url)](.*?)\[/\1\]#ise' => "filter_var('\\2', FILTER_VALIDATE_URL) ? '<a href=\"\\2\" target=\"_blank\">\\2</a>' : '\\0'",
- '#\[(e?mail)\=(.+?)\](.*?)\[/\1\]#ise' => "filter_var('\\2', FILTER_VALIDATE_EMAIL) ? '<a href=\"mailto:\\2\">\\3</a>' : '\\0'",
- '#\[(e?mail)\](.*?)\[/\1\]#ise' => "filter_var('\\2', FILTER_VALIDATE_EMAIL) ? '<a href=\"mailto:\\2\">\\2</a>' : '\\0'",
- '#\[code\=(.+?)\](.+?)\[/code\]#ise' => "bbcode_highlite('\\2', '\\1')",
- '#\[code\](.+?)\[/code\]#ise' => "bbcode_highlite('\\1')",
- );
- $s = preg_replace('#\[code([^\]]*?)\](.*?)\[/code\]#ise', "'[code\\1]'.bbcode_protect('\\2').'[/code]'", $s);
- $s = htmlspecialchars($s, ENT_COMPAT, 'UTF-8');
- return preg_replace(array_keys($bbcode), array_values($bbcode), $s);
- }
- function bbcode_protect($s) {
- return base64_encode(preg_replace('#\\\"#', '"', $s));
- }
- function bbcode_highlite($s, $language=false) {
- $s = trim(base64_decode($s));
- if (!$language) {
- return '<code>' . htmlspecialchars($s, ENT_COMPAT, 'UTF-8') . '</code>';
- }
- $geshi = new GeSHi($s, $language);
- $geshi->enable_classes(true);
- $geshi->set_header_type(GESHI_HEADER_DIV);
- $geshi->enable_keyword_links(false);
- $geshi->set_tab_width(4);
- $output = $geshi->parse_code();
- if ($geshi->error()) {
- return false;
- }
- head('stylesheet', 'geshi/' . $language, 'screen');
- return '<div class="geshi">' . $output . '</div>';
- }
Commentaires