[ Index ]
 

Code source de SPIP 1.9.2c

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/ecrire/inc/ -> sax.php (source)

   1  <?php
   2  
   3  /***************************************************************************\
   4   *  SPIP, Systeme de publication pour l'internet                           *
   5   *                                                                         *
   6   *  Copyright (c) 2001-2007                                                *
   7   *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
   8   *                                                                         *
   9   *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
  10   *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
  11  \***************************************************************************/
  12  
  13  if (!defined("_ECRIRE_INC_VERSION")) return;
  14  
  15  include_spip('inc/filtres');
  16  include_spip('inc/charsets');
  17  include_spip('xml/interfaces');
  18  
  19  // http://doc.spip.org/@xml_debutElement
  20  function xml_debutElement($parser, $name, $attrs)
  21  {
  22      global $phraseur_xml;
  23      $depth = &$phraseur_xml->depth;
  24      $contenu = &$phraseur_xml->contenu;
  25      $ouvrant = &$phraseur_xml->ouvrant;
  26      $reperes = &$phraseur_xml->reperes;
  27  
  28      $t = isset($ouvrant[$depth]) ? $ouvrant[$depth] : ' ';
  29      // espace initial signifie: deja integree au resultat
  30      if ($t[0] != ' ')
  31        {
  32          $phraseur_xml->res .= '<' . $t . '>';
  33          $ouvrant[$depth] = ' ' . $t;
  34        }
  35      $t = $contenu[$depth];
  36      // n'indenter que s'il y a un separateur avant
  37      $phraseur_xml->res .= ereg_replace("[\n\t ]+$",  "\n$depth", $t);
  38      $contenu[$depth] = "";
  39      $att = '';
  40      $sep = ' ';
  41      foreach ($attrs as $k => $v) {
  42        $delim = strpos($v, "'") === false ? "'" : '"';
  43        $val = entites_html($v);
  44        $att .= $sep .  $k . "=" . $delim
  45          . ($delim !== '"' ? str_replace('&quot;', '"', $val) : $val)
  46          . $delim;
  47        $sep = "\n $depth";
  48      }
  49      $depth .= '  ';
  50      $contenu[$depth] = "";
  51      $ouvrant[$depth] = $name . $att;
  52      $reperes[$depth] = xml_get_current_line_number($parser);
  53  }
  54  
  55  // http://doc.spip.org/@xml_finElement
  56  function xml_finElement($parser, $name, $fusion_bal=false)
  57  {
  58      global $phraseur_xml;
  59      $depth = &$phraseur_xml->depth;
  60      $contenu = &$phraseur_xml->contenu;
  61      $ouvrant = &$phraseur_xml->ouvrant;
  62  
  63      $ouv = $ouvrant[$depth];
  64  
  65      if ($ouv[0] != ' ')
  66        $ouvrant[$depth] = ' ' . $ouv;
  67      else $ouv= "";
  68      $t = $contenu[$depth];
  69      $depth = substr($depth, 2);
  70      $t = ereg_replace("[\n\t ]+$", "\n" . $depth, $t);
  71  
  72    // fusion <balise></balise> en <balise />.
  73    // ATTENTION,  certains clients http croient que fusion ==> pas d'atttributs
  74    // en particulier pour les balises Script et A.
  75    // en presence d'attributs ne le faire que si la DTD est dispo et d'accord
  76    // (param fusion_bal)
  77  
  78      if ($t || (($ouv != $name) AND !$fusion_bal))
  79        $phraseur_xml->res .= ($ouv ? ('<' . $ouv . '>') : '') . $t . "</" . $name . ">";
  80      else
  81        $phraseur_xml->res .= ($ouv ? ('<' . $ouv  . ' />') : ("</" .  $name . ">"));
  82  }
  83  
  84  // http://doc.spip.org/@xml_textElement
  85  function xml_textElement($parser, $data)
  86  {
  87      global $phraseur_xml;
  88  
  89      $depth = &$phraseur_xml->depth;
  90      $contenu = &$phraseur_xml->contenu;
  91      $contenu[$depth] .= preg_match('/^script/',$phraseur_xml->ouvrant[$depth])
  92        ? $data
  93        : entites_html($data);
  94  }
  95  
  96  // http://doc.spip.org/@xml_PiElement
  97  function xml_PiElement($parser, $target, $data)
  98  {
  99      global $phraseur_xml;
 100      $depth = &$phraseur_xml->depth;
 101      $contenu = &$phraseur_xml->contenu;
 102      if (strtolower($target) != "php")
 103        $contenu[$depth] .= $data;
 104      else {
 105          ob_start();
 106          eval($data);
 107          $data = ob_get_contents();
 108          ob_end_clean();
 109          $contenu[$depth] .= $data;
 110      }
 111  }
 112  
 113  
 114  // http://doc.spip.org/@xml_defautElement
 115  function xml_defautElement($parser, $data)
 116  {
 117      global $phraseur_xml;
 118      $depth = &$phraseur_xml->depth;
 119      $contenu = &$phraseur_xml->contenu;
 120  
 121      if (!isset($contenu[$depth])) $contenu[$depth]='';
 122      $contenu[$depth] .= $data;
 123  }
 124  
 125  // http://doc.spip.org/@xml_parsestring
 126  function xml_parsestring($phraseur, $data)
 127  {
 128      global $phraseur_xml;
 129      $phraseur_xml->contenu[$phraseur_xml->depth] ='';
 130  
 131      if (!xml_parse($phraseur, $data, true)) {
 132        // ne pas commencer le message par un "<" (cf inc_sax_dist)
 133        $phraseur_xml->err = array(
 134          xml_error_string(xml_get_error_code($phraseur)) .
 135            coordonnees_erreur($phraseur) . "<br />\n" .
 136            (!$phraseur_xml->depth ? '' :
 137             (
 138              _T('erreur_balise_non_fermee') .
 139              " <tt>" .
 140              $phraseur_xml->ouvrant[$phraseur_xml->depth] .
 141              "</tt> " .
 142              _T('ligne') .
 143              $phraseur_xml->reperes[$phraseur_xml->depth] .
 144              " <br />\n" )));
 145      }
 146  }
 147  
 148  // http://doc.spip.org/@coordonnees_erreur
 149  function coordonnees_erreur($xml_parser)
 150  {
 151    return
 152      ' ' .
 153      xml_get_current_line_number($xml_parser) .
 154      ' ' .
 155      xml_get_current_column_number($xml_parser);
 156  }
 157  
 158  // http://doc.spip.org/@inc_sax_dist
 159  function inc_sax_dist($page, $apply=false)
 160  {
 161      global $phraseur_xml;
 162  
 163      // init par defaut si pas fait (espace public)
 164      if (!isset($GLOBALS['phraseur_xml'])) {
 165          $indenter_xml = charger_fonction('indenter_xml', 'inc');
 166          return $indenter_xml($page, $apply);
 167      }
 168  
 169      $xml_parser = xml_parser_create($GLOBALS['meta']['charset']);
 170  
 171      xml_set_element_handler($xml_parser,
 172              array($phraseur_xml, "debutElement"),
 173              array($phraseur_xml, "finElement"));
 174  
 175      xml_set_character_data_handler($xml_parser,
 176                         array($phraseur_xml, "textElement"));
 177  
 178      xml_set_processing_instruction_handler($xml_parser,
 179                         array($phraseur_xml, 'PiElement'));
 180  
 181      xml_set_default_handler($xml_parser,
 182                  array($phraseur_xml, "defautElement"));
 183  
 184      xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false);
 185  
 186      unset($GLOBALS['xhtml_error']);
 187  
 188      if ($apply) {
 189          ob_start();
 190          $page();
 191          $page = ob_get_contents();
 192          ob_end_clean();
 193      }
 194  
 195      // charger la DTD et transcoder les entites,
 196      // et escamoter le doctype que sax mange en php 5
 197      list($doctype,$page) = sax_bug($page);
 198  
 199      $res = $phraseur_xml->phraserTout($xml_parser, $page);
 200  
 201      xml_parser_free($xml_parser);
 202  
 203      if ($res[0] == '<'){
 204          if (!preg_match(_REGEXP_DOCTYPE, substr($res,0,strlen($doctype))))
 205              $res = $doctype . $res;
 206          return $res;
 207      }
 208  
 209      $GLOBALS['xhtml_error'] = $res;
 210  
 211      return $page;
 212  }
 213  
 214  // SAX ne dit pas si une Entite est dans un attribut ou non.
 215  // Les eliminer toutes sinon celles des attributs apparaissent en zone texte!
 216  // Celles fondamentales pour la lecture (lt gt quot amp) sont conservees 
 217  // (d'ailleurs SAX ne les considere pas comme des entites dans un attribut)
 218  // Si la DTD est dispo, on va chercher les entites dedans
 219  // sinon on se rabat sur ce qu'en connait SPIP en standard.
 220  
 221  // http://doc.spip.org/@sax_bug
 222  function sax_bug($data)
 223  {
 224      global  $phraseur_xml;
 225      $doctype = "";
 226  
 227      $r = analyser_doctype($data);
 228      if (!$r) {
 229          $data = _MESSAGE_DOCTYPE . _DOCTYPE_ECRIRE
 230          . preg_replace(_REGEXP_DOCTYPE, '', $data);
 231          $r =  analyser_doctype($data);
 232      }
 233  
 234      list($doctype, $topelement, $avail, $grammaire, $rotlvl) = $r;
 235  
 236          //$data = str_replace('DOCTYPE','doctype',$doctype).substr($data,strlen($doctype));
 237      $file = _DIR_CACHE_XML . preg_replace('/[^\w.]/','_', $rotlvl) . '.gz';
 238  
 239      if (lire_fichier($file, $r)) {
 240              $phraseur_xml->dtc = unserialize($r);
 241      } else {
 242              include_spip('xml/analyser_dtd');
 243                  $phraseur_xml->dtc = charger_dtd($grammaire, $avail);
 244              if (($avail == 'PUBLIC' ) AND $phraseur_xml->dtc)
 245                  ecrire_fichier($file, serialize($phraseur_xml->dtc), true);
 246      }
 247  
 248      if ($phraseur_xml->dtc) {
 249          $trans = array();
 250          
 251          foreach($phraseur_xml->dtc->entites as $k => $v)
 252              if (!strpos(" amp lt gt quot ", $k))
 253                  $trans["&$k;"] = $v;
 254          $data = strtr($data, $trans);
 255      } else 
 256          $data = html2unicode($data, true);
 257          
 258      return array($doctype,unicode2charset($data));
 259  }
 260  
 261  // http://doc.spip.org/@analyser_doctype
 262  function analyser_doctype($data)
 263  {
 264      if (!preg_match(_REGEXP_DOCTYPE, $data, $r))
 265          return array();
 266  
 267      list($doctype,$pi,$co,$pico, $topelement, $avail,$suite) = $r;
 268  
 269      if (!preg_match('/^"([^"]*)"\s*(.*)$/', $suite, $r))
 270          if (!preg_match("/^'([^']*)'\s*(.*)$/", $suite, $r))
 271              return  array();
 272      list(,$rotlvl, $suite) = $r;
 273  
 274      if (!$suite) {
 275          if ($avail != 'SYSTEM') return array();
 276          $grammaire = $rotlvl;
 277          $rotlvl = '';
 278      } else {
 279          if (!preg_match('/^"([^"]*)"\s*$/', $suite, $r))
 280              if (!preg_match("/^'([^']*)'\s*$/", $suite, $r))
 281                  return array();
 282  
 283          $grammaire = $r[1];
 284      }
 285  
 286      return array(substr($doctype,strlen($pico)), $topelement, $avail, $grammaire, $rotlvl);
 287  }
 288  
 289  ?>


Généré le : Wed Nov 21 10:20:27 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics