Wikini

FormulesTeXWikiMedia

PagePrincipale :: DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur :: Vous êtes ec2-52-91-221-160.compute-1.amazonaws.com

  FormulesTeXDansWikini
  • >>



Solution de WikiMedia


En s'inspirant beaucoup de mediawiki, le moteur de WikiPedia, on peut supporter simplement les formules TeX. Suivant que la formule est simple (i_2) ou compliquée (\sum_i...), le rendu se fera en HTML directement, ou sous la forme d'une image png (installation LaTeX requise côté serveur). J'ai repris mediawiki dans wikini pour supporter ce genre d'écritures : \( i_2 \), et \[ i_2 \]. Le premier est associé à une classe CSS "math_inline", le second "math_center", pour pouvoir émuler la mise en page LaTeX. Dernier détail : il y a un mécanisme de cache pour stocker les images/codes html générés pour accélérer le chargement des pages.

Exemple

Marche à suivre :
<?
/*
 * Almost entirely taken from mediawiki :
 *  http://cvs.sourceforge.net/viewcvs.py/wikipedia/phase3/includes/
 */

if (!function_exists("wfEscapeHTML"))
{
  function 
wfEscapeHTML$in )
    {
      return 
str_replace(
             array( 
"&""\""">""<" ),
             array( 
"&amp;""&quot;""&gt;""&lt;" ),
             
$in );
    }
}

if (!
function_exists("linkToMathImage"))
{
  function 
linkToMathImage ($wgMathPath$tex$outputhash )
    {
      global 
$wiki;
      return 
"<img src=\"".$wgMathPath."/"
    
.$outputhash.$wiki->config["ghostscript_png_ext"]
    .
"\" alt=\"".wfEscapeHTML($tex)."\">";
    }
}


if (!
function_exists("renderMath"))
{
  function 
renderMath$tex )
    {
      global 
$wiki;
      
$mf   "math_failure";
      
$munk "math_unknown_error";

      
$math_dir_url $wiki->config["math_dir_url"];
      
$math_dir_sys $wiki->config["math_dir_sys"];
      
$math_tmp_dir $wiki->config["math_tmp_dir"];
      
$math_inputenc $wiki->config["math_inputenc"];
      
$math_render_type $wiki->config["math_render_type"];
      
/*    0 : "Toujours produire une image PNG",
            1 : "HTML si tres simple, autrement PNG",
            2 : "HTML si possible, autrement PNG",
            3 : "Laisser le code ""TeX"" original",
            4 : "Pour les navigateurs modernes" (mathml) */
      
if ($math_render_type == 3)
    return (
'$ '.wfEscapeHTML($tex).' $');

      
$md5 md5($tex);
      
$md5_sql mysql_escape_string(pack("H32"$md5));
      if (
$math_render_type == 0)
    
$sql "SELECT math_outputhash FROM ".$wiki->config["table_prefix"]
      .
"math WHERE math_inputhash = '".$md5_sql."'";
      else
    
$sql "SELECT math_outputhash,math_html_conservativeness,math_html FROM ".$wiki->config["table_prefix"]."math WHERE math_inputhash = '".$md5_sql."'";

      
$res $wiki->Query($sql);

      if( 
$rpage mysql_fetch_object$res ) ) {
    
$outputhash unpack"H32md5",
                  
$rpage->math_outputhash
                  
"                " );
    
$outputhash $outputhash ['md5'];
    if( 
file_exists"$math_dir_sys/$outputhash"
             
.$wiki->config["ghostscript_png_ext"] ) )
      {
        if ((
$math_render_type == 0)
        || (
$rpage->math_html == '')
        || ((
$math_render_type == 1)
            && (
$rpage->math_html_conservativeness != 2))
        || ((
$math_render_type == 4)
            && (
$rpage->math_html_conservativeness == 0)))
          return 
linkToMathImage $wiki->config["math_dir_url"],
                       
$tex$outputhash );
        else
          {
        return 
$rpage->math_html;
          }
      }
      }

      
$cmd $wiki->config["math_texvc_path"]." "
    
.escapeshellarg($math_tmp_dir)." "
    
.escapeshellarg($math_dir_sys)." "
    
.escapeshellarg($tex)." ".escapeshellarg($math_inputenc);
      echo 
$cmd;
      
$contents = `$cmd`;

      if (
strlen($contents) == 0)
    return 
"<b>".$mf." (".$munk." 1): ".wfEscapeHTML($tex)."</b>";
      
$retval substr ($contents01);
      if ((
$retval == "C") || ($retval == "M") || ($retval == "L")) {
    if (
$retval == "C")
      
$conservativeness 2;
    else if (
$retval == "M")
      
$conservativeness 1;
    else
      
$conservativeness 0;
    
$outdata substr ($contents33);

    
$i strpos($outdata"\000");

    
$outhtml substr($outdata0$i);
    
$mathml substr($outdata$i+1);

    
$sql_html "'".mysql_escape_string($outhtml)."'";
    
$sql_mathml "'".mysql_escape_string($mathml)."'";
      } else if ((
$retval == "c") || ($retval == "m") || ($retval == "l"))  {
    
$outhtml substr ($contents33);
    if (
$retval == "c")
      
$conservativeness 2;
    else if (
$retval == "m")
      
$conservativeness 1;
    else
      
$conservativeness 0;
    
$sql_html "'".mysql_escape_string($outhtml)."'";
    
$mathml '';
    
$sql_mathml 'NULL';
      } else if (
$retval == "X") {
    
$outhtml '';
    
$mathml substr ($contents33);
    
$sql_html 'NULL';
    
$sql_mathml "'".mysql_escape_string($mathml)."'";
    
$conservativeness 0;
      } else if (
$retval == "+") {
    
$outhtml '';
    
$mathml '';
    
$sql_html 'NULL';
    
$sql_mathml 'NULL';
    
$conservativeness 0;
      } else {
    if (
$retval == "E")
      
$errmsg wfMsg"math_lexing_error" );
    else if (
$retval == "S")
      
$errmsg wfMsg"math_syntax_error" );
    else if (
$retval == "F")
      
$errmsg wfMsg"math_unknown_function" );
    else
      
$errmsg $munk." ".$retval;
    return 
"<h3>".$mf." (".$errmsg.substr($contents1)."): "
      
.wfEscapeHTML($tex)."</h3>";
      }

      
$outmd5 substr ($contents132);
      if (!
preg_match("/^[a-f0-9]{32}$/"$outmd5))
    return 
"<b>".$mf." (".$munk." 3): ".wfEscapeHTML($tex)."</b>";

      
$outmd5_sql mysql_escape_string(pack("H32"$outmd5));

      
$sql "REPLACE INTO ".$wiki->config["table_prefix"]."math VALUES ('"
    
.$md5_sql."', '".$outmd5_sql."', ".$conservativeness.", ".$sql_html
    
.", ".$sql_mathml.")";
    
      
$res $wiki->Query($sql);
# we don't really care if it fails

    
if (($math_render_type == 0) || ($rpage->math_html == ''
            || ((
$math_render_type == 1) && ($conservativeness != 2))
            || ((
$math_render_type == 4) && ($conservativeness == 0)))
        return 
linkToMathImage($wiki->config["math_dir_url"],
                                   
$tex$outmd5);
    else
        return 
$outhtml;
  }
}

echo 
renderMath($text);
?>

/* Chemin HTTP pour math_img */
    "math_dir_url" => "/wikini/math_img",

        /* Chemin système pour math_img */
    "math_dir_sys" => "/var/httpd/htdocs/wikini/math_img",

        /* Chemin système vers l'exécutable texvc */
    "math_texvc_path" => "/var/httpd/htdocs/wikini/formatters/texvc",

        /* Répertoire système pour les fichiers temporaires */
    "math_tmp_dir" => "/tmp",

    "math_inputenc" => "UTF-8",

    "math_render_type" => "1",
    /* Valeurs possibles pour math_render_type :
            0 : "Toujours produire une image PNG",
            1 : "HTML si tres simple, autrement PNG",
            2 : "HTML si possible, autrement PNG",
            3 : "Laisser le code TeX original",
            4 : "Pour les navigateurs modernes" (mathml) */

    "ghostscript_png_ext" => ".png",
    /* Valeurs possibles pour ghostscript_png_ext :
            Versions anciennes de ghostscript : ".png.0"
            Versions récentes de ghostscript : ".png" */

@@ -117,6 +119,26 @@
                {
                        return $matches[1];
                }
+                // \(math\)
+                else if (preg_match("/^[\\\\]\\((.*)[\\\\]\\)$/s",
+                                    $thing, $matches))
+                {
+                        $output = "<div class=\"math_inline\">";
+                        $output .= $wiki->Format(trim($matches[1]), "math");
+                        $output .= "</div>";
+
+                        return $output;
+                }
+                // \[math\]
+                else if (preg_match("/^[\\\\]\\[(.*)[\\\\]\\]$/s",
+                                    $thing, $matches))
+                {
+                        $output = "<div class=\"math_center\">";
+                        $output .= $wiki->Format(trim($matches[1]), "math");
+                        $output .= "</div>";
+
+                        return $output;
+                }
                // code text
                else if (preg_match("/^\%\%(.*)\%\%$/s", $thing, $matches))
                {
@@ -278,6 +300,8 @@
 $text = trim($text)."\n";
 $text = preg_replace_callback(
        "/(\%\%.*?\%\%|".
+        "[\\\\]\\[.*?[\\\\]\\]|".
+        "[\\\\]\\(.*?[\\\\]\\)|".
        "\"\".*?\"\"|".
        "\[\[.*?\]\]|".
        "\b[a-z]+:\/\/\S+|".

USE la_table_wikini; -- En général c'est tout simplement "wikini" ici
CREATE TABLE `wikini_math` (
  `math_inputhash` varchar(16) NOT NULL default '',
  `math_outputhash` varchar(16) NOT NULL default '',
  `math_html_conservativeness` tinyint(1) NOT NULL default '0',
  `math_html` text,
  `math_mathml` text,
  UNIQUE KEY `math_inputhash` (`math_inputhash`)
);

div.math_inline { display: inline; }
div.math_center { text-align: center; }


Et voilà.

-- DavidDecotigny

Salut,

ça serait vraiment bien si on n'avais pas besoin d'installer LaTeX, Ghostscript... sur le serveur
Peut-être existe-il un serveur permettant de générer les images ?
-- SebCls?
Il n'y a pas de commentaire sur cette page. [Afficher commentaires/formulaire]