Skip to content
Extraits de code Groupes Projets
inc_texte.php3 30 ko
Newer Older
<?php
Yannick Patois's avatar
Yannick Patois a validé

Fil's avatar
Fil a validé
/***************************************************************************\
 *  SPIP, Systeme de publication pour l'internet                           *
 *                                                                         *
 *  Copyright (c) 2001-2005                                                *
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
 *                                                                         *
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
\***************************************************************************/


Yannick Patois's avatar
Yannick Patois a validé
//
if (!defined("_ECRIRE_INC_VERSION")) return;
Yannick Patois's avatar
Yannick Patois a validé

include_ecrire ("inc_filtres");
Yannick Patois's avatar
Yannick Patois a validé

//
// Initialisation de quelques variables globales
// (on peut les modifier globalement dans mes_fonctions,
//  OU individuellement pour chaque type de page dans article, rubrique, etc.
// cf doc...)
Yannick Patois's avatar
Yannick Patois a validé
//
function tester_variable($nom_var, $val){
Fil's avatar
 
Fil a validé
	if (!isset($GLOBALS[$nom_var])) {
		return false;
	}
	return true;
tester_variable('debut_intertitre', "\n<h3 class=\"spip\">");
tester_variable('fin_intertitre', "</h3>\n");
Fil's avatar
Fil a validé
tester_variable('ligne_horizontale', "\n<hr class=\"spip\" />\n");
ARNO*'s avatar
ARNO* a validé
tester_variable('ouvre_ref', '&nbsp;[');
tester_variable('ferme_ref', ']');
tester_variable('ouvre_note', '[');
tester_variable('ferme_note', '] ');
tester_variable('les_notes', '');
tester_variable('compt_note', 0);
tester_variable('nombre_surligne', 4);
tester_variable('url_glossaire_externe', "http://@lang@.wikipedia.org/wiki/");
Antoine Pitrou's avatar
Antoine Pitrou a validé

// On ne prend la $puce_rtl par defaut que si $puce n'a pas ete redefinie
Yannick Patois's avatar
Yannick Patois a validé

Antoine Pitrou's avatar
Antoine Pitrou a validé
//if (!tester_variable('puce', "<li class='spip_puce' style='list-style-image: url(puce.gif)'>")) {
if (!tester_variable('puce', "<img class='spip_puce' src='puce.gif' alt='-' />&nbsp;")) {
	tester_variable('puce_rtl', "<img class='spip_puce' src='puce_rtl.gif' alt='-' />&nbsp;");
Yannick Patois's avatar
Yannick Patois a validé


Yannick Patois's avatar
Yannick Patois a validé

// Ne pas afficher le chapo si article virtuel
function nettoyer_chapo($chapo){
	if (substr($chapo,0,1) == "="){
Antoine Pitrou's avatar
Antoine Pitrou a validé
		$chapo = "";
	}
	return $chapo;
}

// Mise de cote des echappements
Yannick Patois's avatar
Yannick Patois a validé

// Definition de la regexp de echappe_html
define ('__regexp_echappe',
		"/(" . "<html>((.*?))<\/html>" . ")|("	#html
		. "<code>((.*?))<\/code>" . ")|("	#code
		. "<(cadre|frame)>((.*?))<\/(cadre|frame)>" #cadre
		. "<(poesie|poetry)>((.*?))<\/(poesie|poetry)>" #poesie
define('__preg_img', ',<(img|doc|emb)([0-9]+)(\|([^>]*))?'.'>,i');
Yannick Patois's avatar
Yannick Patois a validé

function echappe_html($letexte, $source='SOURCEPROPRE', $no_transform=false) {
	if (preg_match_all(__regexp_echappe, $letexte, $matches, PREG_SET_ORDER))
	foreach ($matches as $regs) {
		$marqueur_echap = "@@SPIP_$source$num_echap@@";
Yannick Patois's avatar
Yannick Patois a validé

		if ($no_transform) {	// echappements bruts
			$les_echap[$num_echap] = $regs[0];
		}
		else
Fil's avatar
Fil a validé
		if ($regs[1]) {
			// Echapper les <html>...</ html>
			$les_echap[$num_echap] = $regs[2];
		}
		else
Fil's avatar
Fil a validé
		if ($regs[4]) {
			// Echapper les <code>...</ code>
			$lecode = entites_html($regs[5]);

Fil's avatar
Fil a validé
			// supprimer les sauts de ligne debut/fin (mais pas les espaces => ascii art).
			$lecode = ereg_replace("^\n+|\n+$", "", $lecode);

			// ne pas mettre le <div...> s'il n'y a qu'une ligne
			if (is_int(strpos($lecode,"\n"))) {
				$lecode = nl2br("<div style='text-align: left;' class='spip_code' dir='ltr'><code>".$lecode."</code></div>");
				$marqueur_echap = "</no p>$marqueur_echap<no p>";
			} else
				$lecode = "<span class='spip_code' dir='ltr'><code>".$lecode."</code></span>";
			$lecode = str_replace("\t", "&nbsp; &nbsp; &nbsp; &nbsp; ", $lecode);
			$lecode = str_replace("  ", " &nbsp;", $lecode);
			$les_echap[$num_echap] = $lecode;
Fil's avatar
Fil a validé
		if ($regs[7]) {
			// Echapper les <cadre>...</cadre>
			$lecode = trim(entites_html($regs[9]));
			$total_lignes = substr_count($lecode, "\n") + 1;
			$les_echap[$num_echap] = "<form action=\"/\" method=\"get\"><div><textarea readonly='readonly' cols='40' rows='$total_lignes' class='spip_cadre' dir='ltr'>".$lecode."</textarea></div></form>";
			// Les marques ci-dessous indiquent qu'on ne veut pas paragrapher
			$marqueur_echap = "\n\n</no p>$marqueur_echap<no p>\n\n";
		else
		if ($regs[12]) {
			$lecode = $regs[14];
			$lecode = ereg_replace("\n[[:space:]]*\n", "\n&nbsp;\n",$lecode);
			$lecode = str_replace("\r", "\n", $lecode); # gestion des \r a revoir !
			$lecode = "<div class=\"spip_poesie\"><div>".ereg_replace("\n+", "</div>\n<div>", $lecode)."</div></div>";
			$marqueur_echap = "\n\n</no p>$marqueur_echap<no p>\n\n";
ARNO*'s avatar
ARNO* a validé
			$les_echap[$num_echap] = propre($lecode);
ARNO*'s avatar
ARNO* a validé
		} 
Yannick Patois's avatar
Yannick Patois a validé

		$letexte = str_replace($regs[0], $marqueur_echap, $letexte);
Yannick Patois's avatar
Yannick Patois a validé
	}
	// Gestion du TeX
	if (!(strpos($letexte, "<math>") === false)) {
Fil's avatar
Fil a validé
		$letexte = traiter_math($letexte, $les_echap, $num_echap, $source);
ARNO*'s avatar
ARNO* a validé
	}

	return array($letexte, $les_echap);
Yannick Patois's avatar
Yannick Patois a validé
}

// Traitement final des echappements
function echappe_retour($letexte, $les_echap, $source='SOURCEPROPRE') {
	$expr = ",@@SPIP_$source([0-9]+)@@,";
	if (preg_match_all($expr, $letexte, $regs, PREG_SET_ORDER)) {
		foreach ($regs as $reg) {
			$rempl = $les_echap[$reg[1]];
			$letexte = str_replace($reg[0], $rempl, $letexte);
		}
	}
	return $letexte;

// fonction en cas de texte extrait d'un serveur distant:
// on ne sait pas (encore) rapatrier les documents joints

function supprime_img($letexte) {
	$message = _T('img_indisponible');
	preg_replace(__preg_img, "($message)", $letexte);
Fil's avatar
Fil a validé
//
// Gerer les outils mb_string
//
function spip_substr($c, $start=0, $end='') {
	include_ecrire('inc_charsets');
Fil's avatar
Fil a validé
	if (init_mb_string()) {
		if ($end)
			return mb_substr($c, $start, $end);
		else
			return mb_substr($c, $start);
	}

	// methode substr normale
	else {
		if ($end)
			return substr($c, $start, $end);
		else
			return substr($c, $start);
	}
}

function spip_strlen($c) {
	include_ecrire('inc_charsets');
Fil's avatar
Fil a validé
	if (init_mb_string())
		return mb_strlen($c);
	else
		return strlen($c);
}
// fin mb_string


function couper($texte, $taille=50) {
	$texte = substr($texte, 0, 400 + 2*$taille); /* eviter de travailler sur 10ko pour extraire 150 caracteres */

	// on utilise les \r pour passer entre les gouttes
	$texte = str_replace("\r", "\n", $texte);

	// sauts de ligne et paragraphes
	$texte = ereg_replace("\n\n+", "\r", $texte);
Fil's avatar
Fil a validé
	$texte = ereg_replace("<(p|br)( [^>]*)?".">", "\r", $texte);
	// supprimer les traits, lignes etc
	$texte = ereg_replace("(^|\r|\n)(-[-#\*]*|_ )", "\r", $texte);

	// supprimer les tags
	$texte = supprimer_tags($texte);
	$texte = trim(str_replace("\n"," ", $texte));
	$texte .= "\n";	// marquer la fin

	// travailler en accents charset
	$texte = filtrer_entites($texte);

	// remplacer les liens
	if (preg_match_all(',[[]([^][]*)->(>?)([^][]*)[]],', $texte, $regs, PREG_SET_ORDER))
		foreach ($regs as $reg) {
			if (strlen($reg[1]))
				$titre = $reg[1];
			else
				list(,,$titre) = extraire_lien($reg);
			$texte = str_replace($reg[0], $titre, $texte);
		}
Yannick Patois's avatar
Yannick Patois a validé

	// supprimer les notes
	$texte = ereg_replace("\[\[([^]]|\][^]])*\]\]", "", $texte);
Yannick Patois's avatar
Yannick Patois a validé

	$texte = ereg_replace("[}{]", "", $texte);
Yannick Patois's avatar
Yannick Patois a validé

Fil's avatar
Fil a validé
	$texte = ereg_replace("(^|\r)\|.*\|\r", "\r", $texte);
Fil's avatar
Fil a validé
	$long = spip_substr($texte, 0, max($taille-4,1));
Fil's avatar
Fil a validé
	$court = ereg_replace("([^[:space:]][[:space:]]+)[^[:space:]]*\n?$", "\\1", $long);
	$points = '&nbsp;(...)';

	// trop court ? ne pas faire de (...)
Fil's avatar
Fil a validé
	if (spip_strlen($court) < max(0.75 * $taille,2)) {
Fil's avatar
Fil a validé
		$long = spip_substr($texte, 0, $taille);
		$texte = ereg_replace("([^[:space:]][[:space:]]+)[^[:space:]]*$", "\\1", $long);
		// encore trop court ? couper au caractere
Fil's avatar
Fil a validé
		if (spip_strlen($texte) < 0.75 * $taille)
Fil's avatar
Fil a validé
	if (strpos($texte, "\n"))	// la fin est encore la : c'est qu'on n'a pas de texte de suite
	// remettre les paragraphes
	$texte = ereg_replace("\r+", "\n\n", $texte);

Fil's avatar
Fil a validé
	// supprimer l'eventuelle entite finale mal coupee
	$texte = preg_replace('/&#?[a-z0-9]*$/', '', $texte);
Fil's avatar
Fil a validé

Yannick Patois's avatar
Yannick Patois a validé
}

// prendre <intro>...</intro> sinon couper a la longueur demandee
Yannick Patois's avatar
Yannick Patois a validé
function couper_intro($texte, $long) {
	$texte = extraire_multi(eregi_replace("(</?)intro>", "\\1intro>", $texte)); // minuscules
Yannick Patois's avatar
Yannick Patois a validé
	while ($fin = strpos($texte, "</intro>")) {
		$zone = substr($texte, 0, $fin);
		$texte = substr($texte, $fin + strlen("</intro>"));
		if ($deb = strpos($zone, "<intro>") OR substr($zone, 0, 7) == "<intro>")
			$zone = substr($zone, $deb + 7);
		$intro .= $zone;
	}

	if ($intro)
Yannick Patois's avatar
Yannick Patois a validé
	else
		$intro = couper($texte, $long);

	// supprimer un eventuel chapo redirecteur =http:/.....
	$intro = preg_replace(',^=[^[:space:]]+,','',$intro);
Yannick Patois's avatar
Yannick Patois a validé

	return $intro;
}


Yannick Patois's avatar
Yannick Patois a validé

// Securite : empecher l'execution de code PHP ou javascript ou autre malice
function interdire_scripts($source) {
	$source = preg_replace(",<(\%|\?|[[:space:]]*(script|base)),ims", "&lt;\\1", $source);
Yannick Patois's avatar
Yannick Patois a validé
}

// Securite : utiliser SafeHTML s'il est present dans ecrire/safehtml/
function safehtml($t) {
	static $a;
	define_once('XML_HTMLSAX3', _DIR_RESTREINT."safehtml/classes/");
	if (@file_exists(XML_HTMLSAX3.'safehtml.php')) {
		include_local(XML_HTMLSAX3.'safehtml');
		$a =& new safehtml();
		$t = $a->parse($t);
	}
	return $t;
}
// Correction typographique francaise
Yannick Patois's avatar
Yannick Patois a validé
function typo_fr($letexte) {
	static $trans;
Antoine Pitrou's avatar
Antoine Pitrou a validé

	// Nettoyer 160 = nbsp ; 187 = raquo ; 171 = laquo ; 176 = deg ; 147 = ldquo; 148 = rdquo
Antoine Pitrou's avatar
Antoine Pitrou a validé
	if (!$trans) {
		$trans = array(
			"&nbsp;" => "~",
			"&raquo;" => "&#187;",
			"&laquo;" => "&#171;",
			"&rdquo;" => "&#148;",
			"&ldquo;" => "&#147;",
Antoine Pitrou's avatar
Antoine Pitrou a validé
			"&deg;" => "&#176;"
		);
		$chars = array(160 => '~', 187 => '&#187;', 171 => '&#171;', 148 => '&#148;', 147 => '&#147;', 176 => '&#176;');
Fil's avatar
 
Fil a validé

		include_ecrire('inc_charsets');
Antoine Pitrou's avatar
Antoine Pitrou a validé
		while (list($c, $r) = each($chars)) {
			$c = unicode2charset(charset2unicode(chr($c), 'iso-8859-1', 'forcer'));
			$trans[$c] = $r;
		}
Yannick Patois's avatar
Yannick Patois a validé
	}

Fil's avatar
Fil a validé
	$letexte = strtr($letexte, $trans);
Fil's avatar
 
Fil a validé

Yannick Patois's avatar
Yannick Patois a validé
	$cherche1 = array(
Yannick Patois's avatar
Yannick Patois a validé
		/* 2 */ 	'/((^|[^\#0-9a-zA-Z\&])[\#0-9a-zA-Z]*)\;/',
		/* 3 */		'/&#187;| --?,|:([^0-9]|$)/',
		/* 4 */		'/([^<!?])([!?])/',
		/* 5 */		'/&#171;|(M(M?\.|mes?|r\.?)|[MnN]&#176;) /'
Yannick Patois's avatar
Yannick Patois a validé
	);
	$remplace1 = array(
		/* 1		'<i class="spip">\1</i>', */
Yannick Patois's avatar
Yannick Patois a validé
		/* 2 */		'\1~;',
Yannick Patois's avatar
Yannick Patois a validé
	);
	$letexte = preg_replace($cherche1, $remplace1, $letexte);
Yannick Patois's avatar
Yannick Patois a validé
	$letexte = ereg_replace(" *~+ *", "~", $letexte);

	$cherche2 = array(
Yannick Patois's avatar
Yannick Patois a validé
		'/~/'
	);
	$remplace2 = array(
		'\1:',
		'&nbsp;'
	);
	$letexte = preg_replace($cherche2, $remplace2, $letexte);
Yannick Patois's avatar
Yannick Patois a validé

Antoine Pitrou's avatar
Antoine Pitrou a validé
	return $letexte;
Yannick Patois's avatar
Yannick Patois a validé
}

// rien sauf les "~" et "-,"
function typo_en($letexte) {
Fil's avatar
Fil a validé
	$cherche1 = array(
Fil's avatar
Fil a validé
	);
	$remplace1 = array(
Fil's avatar
Fil a validé
	);
	$letexte = preg_replace($cherche1, $remplace1, $letexte);
Antoine Pitrou's avatar
Antoine Pitrou a validé
	$letexte = str_replace("&nbsp;", "~", $letexte);
	$letexte = ereg_replace(" *~+ *", "~", $letexte);

	$cherche2 = array(
Fil's avatar
Fil a validé

	$letexte = preg_replace($cherche2, $remplace2, $letexte);
function typo($letexte) {
Yannick Patois's avatar
Yannick Patois a validé

	// Echapper les codes <html> etc
	list($letexte, $les_echap) = echappe_html($letexte, "SOURCETYPO");

Fil's avatar
Fil a validé
	// Appeler les fonctions de pre-traitement
	$letexte = pipeline('pre_typo', $letexte);
	// old style
	if (function_exists('avant_typo'))
		$letexte = avant_typo($letexte);
	// Caracteres de controle "illegaux"
	$letexte = corriger_caracteres($letexte);

	// Proteger les caracteres typographiques a l'interieur des tags html
	$protege = "!':;?";
	$illegal = "\x1\x2\x3\x4\x5";
	if (preg_match_all("/<[a-z!][^<>!':;\?]*[!':;\?][^<>]*>/ims",
	$letexte, $regs, PREG_SET_ORDER)) {
		foreach ($regs as $reg) {
			$insert = $reg[0];
			// hack: on transforme les caracteres a proteger en les remplacant
			// par des caracteres "illegaux". (cf corriger_caracteres())
			$insert = strtr($insert, $protege, $illegal);
			$letexte = str_replace($reg[0], $insert, $letexte);
		}
	}

	// zouli apostrophe
	$letexte = str_replace("'", "&#8217;", $letexte);

	// typo francaise ou anglaise ?
	// $lang_typo est fixee dans l'interface privee pour editer
	// un texte anglais en interface francaise (ou l'inverse) ;
	// sinon determiner la typo en fonction de la langue
	if (!$lang = $GLOBALS['lang_typo']) {
Antoine Pitrou's avatar
Antoine Pitrou a validé
		$lang = lang_typo($spip_lang);
Antoine Pitrou's avatar
Antoine Pitrou a validé
	if ($lang == 'fr')
Yannick Patois's avatar
Yannick Patois a validé
		$letexte = typo_fr($letexte);
	else
		$letexte = typo_en($letexte);
Antoine Pitrou's avatar
Antoine Pitrou a validé

	// Retablir les caracteres proteges
	$letexte = strtr($letexte, $illegal, $protege);

Fil's avatar
Fil a validé
	// Appeler les fonctions de post-traitement
	$letexte = pipeline('post_typo', $letexte);
	// old style
	if (function_exists('apres_typo'))
		$letexte = apres_typo($letexte);

	# un message pour abs_url - on est passe en mode texte
	$GLOBALS['mode_abs_url'] = 'texte';

	// reintegrer les echappements
	return echappe_retour($letexte, $les_echap, "SOURCETYPO");
Yannick Patois's avatar
Yannick Patois a validé
}

function charger_generer_url() {
	// Traitement des liens internes
	if (!_DIR_RESTREINT)
	else if (@file_exists("inc-urls" . _EXTENSIONS_PHP))
		include_local("inc-urls");
	else	include_local("inc-urls-".$GLOBALS['type_urls']);
Fil's avatar
 
Fil a validé
// cette fonction est tordue : on lui passe un tableau correspondant au match
// de la regexp ci-dessous, et elle retourne le texte a inserer a la place
// et le lien "brut" a usage eventuel de redirection...
function extraire_lien ($regs) {
Fil's avatar
Fil a validé
	$lien_texte = $regs[1];
	$lien_url = entites_html(trim($regs[3]));
Fil's avatar
 
Fil a validé
	$compt_liens++;
	$lien_interne = false;
Fil's avatar
Fil a validé
	if (ereg('^[[:space:]]*(art(icle)?|rub(rique)?|br(.ve)?|aut(eur)?|mot|site|doc(ument)?|im(age|g))?[[:space:]]*([[:digit:]]+)(#.*)?[[:space:]]*$', $lien_url, $match)) {
		$ancre = $match[9];
		$type_lien = substr($match[1], 0, 2);
Fil's avatar
 
Fil a validé
		$lien_interne=true;
		$class_lien = "in";
		charger_generer_url();
		switch ($type_lien) {
Fil's avatar
 
Fil a validé
			case 'ru':
				$lien_url = generer_url_rubrique($id_lien);
				if (!$lien_texte) {
					$req = "select titre from spip_rubriques where id_rubrique=$id_lien";
					$row = @spip_fetch_array(@spip_query($req));
Fil's avatar
 
Fil a validé
					$lien_texte = $row['titre'];
				}
				break;
			case 'br':
				$lien_url = generer_url_breve($id_lien);
				if (!$lien_texte) {
					$req = "select titre from spip_breves where id_breve=$id_lien";
					$row = @spip_fetch_array(@spip_query($req));
Fil's avatar
 
Fil a validé
					$lien_texte = $row['titre'];
				}
				break;
			case 'au':
				$lien_url = generer_url_auteur($id_lien);
				if (!$lien_texte) {
					$req = "select nom from spip_auteurs where id_auteur = $id_lien";
					$row = @spip_fetch_array(@spip_query($req));
Fil's avatar
 
Fil a validé
					$lien_texte = $row['nom'];
				}
				break;
			case 'mo':
				$lien_url = generer_url_mot($id_lien);
				if (!$lien_texte) {
					$req = "select titre from spip_mots where id_mot=$id_lien";
					$row = @spip_fetch_array(@spip_query($req));
Fil's avatar
 
Fil a validé
					$lien_texte = $row['titre'];
				}
				break;
			case 'im':
			case 'do':
				$lien_url = generer_url_document($id_lien);
				if (!$lien_texte) {
					$req = "select titre,fichier from spip_documents
					WHERE id_document=$id_lien";
					$row = @spip_fetch_array(@spip_query($req));
					$lien_texte = $row['titre'];
					if (!$lien_texte)
						$lien_texte = ereg_replace("^.*/","",$row['fichier']);
				}
Fil's avatar
Fil a validé
				break;
Fil's avatar
 
Fil a validé
			case 'si':
				# attention dans le cas des sites le lien pointe non pas sur
				# la page locale du site, mais directement sur le site lui-meme
				$row = @spip_fetch_array(@spip_query("SELECT nom_site,url_site
				FROM spip_syndic WHERE id_syndic=$id_lien"));
Fil's avatar
 
Fil a validé
				if ($row) {
					$lien_url = $row['url_site'];
					if (!$lien_texte)
						$lien_texte = typo($row['nom_site']);
				}
				break;
			default:
				$lien_url = generer_url_article($id_lien);
				if (!$lien_texte) {
					$req = "select titre from spip_articles where id_article=$id_lien";
					$row = @spip_fetch_array(@spip_query($req));
Fil's avatar
 
Fil a validé
					$lien_texte = $row['titre'];
Fil's avatar
 
Fil a validé
				}
				break;
		}
		$lien_url .= $ancre;

		// supprimer les numeros des titres
		$lien_texte = supprimer_numero($lien_texte);
Antoine Pitrou's avatar
Antoine Pitrou a validé
	}
	else if (preg_match(',^\?(.*)$,s', $lien_url, $regs)) {
Antoine Pitrou's avatar
Antoine Pitrou a validé
		// Liens glossaire
		$lien_url = substr($lien_url, 1);
		$class_lien = "glossaire";
	}
	else {
		// Liens non automatiques
Fil's avatar
 
Fil a validé
		$class_lien = "out";
		// texte vide ?
		if ((!$lien_texte) and (!$lien_interne)) {
			$lien_texte = str_replace('"', '', $lien_url);
Fil's avatar
 
Fil a validé
			if (strlen($lien_texte)>40)
				$lien_texte = substr($lien_texte,0,35).'...';
			$class_lien = "url";
			$lien_texte = "<html>$lien_texte</html>";
Fil's avatar
 
Fil a validé
		}
		// petites corrections d'URL
		if (preg_match(",^www\.[^@]+$,",$lien_url))
Fil's avatar
 
Fil a validé
			$lien_url = "http://".$lien_url;
Antoine Pitrou's avatar
Antoine Pitrou a validé
		else if (strpos($lien_url, "@") && email_valide($lien_url))
			$lien_url = "mailto:".$lien_url;
Fil's avatar
 
Fil a validé
	}

	$insert = "<a href=\"$lien_url\" class=\"spip_$class_lien\""
Fil's avatar
Fil a validé
		.">".typo($lien_texte)."</a>";
Fil's avatar
 
Fil a validé

	return array($insert, $lien_url, $lien_texte);
Fil's avatar
 
Fil a validé
}
Fil's avatar
Fil a validé
//
// Tableaux
//
function traiter_tableau($bloc) {

	// Decouper le tableau en lignes
	preg_match_all(',([|].*)[|]\n,Ums', $bloc, $regs, PREG_PATTERN_ORDER);
	$lignes = array();

Fil's avatar
Fil a validé
	// Traiter chaque ligne
	foreach ($regs[1] as $ligne) {
		$l ++;

		// Gestion de la premiere ligne :
		if ($l == 1) {
Fil's avatar
Fil a validé
		// - <caption> et summary dans la premiere ligne :
		//   || caption | summary || (|summary est optionnel)
			if (preg_match(',^\|\|([^|]*)(\|(.*))?\|$,s', $ligne, $cap)) {
Fil's avatar
Fil a validé
				$l = 0;
Fil's avatar
Fil a validé
				if ($caption = trim($cap[1]))
					$debut_table .= "<caption>".$caption."</caption>\n";
Fil's avatar
Fil a validé
				$summary = ' summary="'.entites_html(trim($cap[3])).'"';
Fil's avatar
Fil a validé
			}
		// - <thead> sous la forme |{{titre}}|{{titre}}|
		//   Attention thead oblige a avoir tbody
			else if (preg_match(',^(\|([[:space:]]*{{[^}]+}}[[:space:]]*|<))+$,s',
Fil's avatar
Fil a validé
				$ligne, $thead)) {
			  	preg_match_all("/\|([^|]*)/", $ligne, $cols);
				$ligne='';$cols= $cols[1];
				$colspan=1;
				for($c=count($cols)-1; $c>=0; $c--) {
					$attr='';
					if($cols[$c]=='<') {
					  $colspan++;
					} else {
					  if($colspan>1) {
						$attr= " colspan='$colspan'";
						$colspan=1;
					  }
					  $ligne= "<th scope='col'$attr>$cols[$c]</th>$ligne";
					}
				}

				$debut_table .= "<thead><tr class='row_first'>".
					$ligne."</tr></thead>\n";
Fil's avatar
Fil a validé
				$l = 0;
			}
		}

		// Sinon ligne normale
		if ($l) {
			// Gerer les listes a puce dans les cellules
			if (ereg("\n-[*#]", $ligne))
				$ligne = traiter_listes($ligne);

Fil's avatar
Fil a validé
			// Pas de paragraphes dans les cellules
			$ligne = preg_replace(",\n\n+,", "<br />\n", $ligne);

			// tout mettre dans un tableau 2d
			preg_match_all("/\|([^|]*)/", $ligne, $cols);
			$lignes[]= $cols[1];
		}
	}
	// maintenant qu'on a toutes les cellules
	// on prepare une liste de rowspan par défaut
	$rowspans= array_fill(0, count($lignes[0]), 1);

	// et on parcours le tableau a l'envers pour ramasser les
	// colspan et rowspan en passant
	for($l=count($lignes)-1; $l>=0; $l--) {
		$cols= $lignes[$l];
		$colspan=1;
		$ligne='';

		for($c=count($cols)-1; $c>=0; $c--) {
			$attr='';
			if($cols[$c]=='<') {
			  $colspan++;

			} elseif($cols[$c]=='^') {
			  $rowspans[$c]++;

			} else {
			  if($colspan>1) {
				$attr.= " colspan='$colspan'";
				$colspan=1;
			  }
			  if($rowspans[$c]>1) {
				$attr.= " rowspan='$rowspans[$c]'";
				$rowspans[$c]=1;
			  }
			  $ligne= '<td'.$attr.'>'.$cols[$c].'</td>'.$ligne;
			}

		// ligne complete
		$class = 'row_'.alterner($l+1, 'even', 'odd');
		$html = "<tr class=\"$class\">" . $ligne . "</tr>\n".$html;
Fil's avatar
Fil a validé
	return "\n\n</no p><table class=\"spip\"$summary>\n"
Fil's avatar
Fil a validé
		. $debut_table
		. "<tbody>\n"
Fil's avatar
Fil a validé
		. "</tbody>\n"
		. "</table><no p>\n\n";
}


// Traitement des listes (merci a Michael Parienti)
//
function traiter_listes ($texte) {
	$parags = preg_split(",\n[[:space:]]*\n,", $texte);
	unset($texte);

	// chaque paragraphe est traite a part
	while (list(,$para) = each($parags)) {
		$niveau = 0;
		$lignes = explode("\n-", "\n" . $para);

		// ne pas toucher a la premiere ligne
		list(,$debut) = each($lignes);
		$texte .= $debut;

		// chaque item a sa profondeur = nb d'etoiles
		unset ($type);
		while (list(,$item) = each($lignes)) {
			preg_match(",^([*]*|[#]*)([^*#].*)$,s", $item, $regs);
			$profond = strlen($regs[1]);

			if ($profond > 0) {
				unset ($ajout);

				// changement de type de liste au meme niveau : il faut
				// descendre un niveau plus bas, fermer ce niveau, et
				// remonter
				$nouv_type = (substr($item,0,1) == '*') ? 'ul' : 'ol';
				$change_type = ($type AND ($type <> $nouv_type) AND ($profond == $niveau)) ? 1 : 0;
				// d'abord traiter les descentes
				while ($niveau > $profond - $change_type) {
					$ajout .= $pile_li[$niveau];
					$ajout .= $pile_type[$niveau];
Fil's avatar
Fil a validé
					if (!$change_type)
						unset ($pile_li[$niveau]);
				// puis les identites (y compris en fin de descente)
				if ($niveau == $profond && !$change_type) {
Fil's avatar
Fil a validé
					$ajout .= $pile_li[$niveau];
				}

				// puis les montees (y compris apres une descente un cran trop bas)
				while ($niveau < $profond) {
					if ($niveau == 0) $ajout .= "\n\n";
Fil's avatar
Fil a validé
					$ajout .= "</no p>"."<$type class=\"spip\">";
					$pile_type[$niveau] = "</$type>"."<no p>";
				$ajout .= "<li class=\"spip\">";
				$pile_li[$profond] = "</li>";
Antoine Pitrou's avatar
Antoine Pitrou a validé
			else {
			$texte .= $ajout . $regs[2];
		unset ($ajout);
		while ($niveau > 0) {
			$ajout .= $pile_li[$niveau];
			$ajout .= $pile_type[$niveau];
			$niveau --;
		}
		$texte .= $ajout;

		// paragraphe
		$texte .= "\n\n";
	}

	// sucrer les deux derniers \n
	return substr($texte, 0, -2);
}

Yannick Patois's avatar
Yannick Patois a validé
// Nettoie un texte, traite les raccourcis spip, la typo, etc.
function traiter_raccourcis_generale($letexte) {
Antoine Pitrou's avatar
Antoine Pitrou a validé
	global $debut_intertitre, $fin_intertitre, $ligne_horizontale, $url_glossaire_externe;
Yannick Patois's avatar
Yannick Patois a validé
	global $compt_note;
Yannick Patois's avatar
Yannick Patois a validé
	global $ouvre_ref;
	global $ferme_ref;
	global $ouvre_note;
	global $ferme_note;
Fil's avatar
Fil a validé
	global $lang_dir;
Yannick Patois's avatar
Yannick Patois a validé

Fil's avatar
Fil a validé
	// Appeler les fonctions de pre_traitement
	$letexte = pipeline('pre_propre', $letexte);
	// old style
	if (function_exists('avant_propre'))
		$letexte = avant_propre($letexte);
	if (!$lang_dir) {
Fil's avatar
Fil a validé
		$lang_dir = lang_dir($GLOBALS['spip_lang']);
	if ($lang_dir == 'rtl' AND $GLOBALS['puce_rtl'])
		$puce = $GLOBALS['puce_rtl'];
	else
		$puce = $GLOBALS['puce'];
	// Harmoniser les retours chariot
	$letexte = preg_replace(",\r\n?,", "\n", $letexte);

Yannick Patois's avatar
Yannick Patois a validé
	// Corriger HTML
	$letexte = preg_replace(",</?p>,i", "\n\n\n", $letexte);
Yannick Patois's avatar
Yannick Patois a validé

	//
	// Notes de bas de page
	//
	$regexp = ',\[\[(.*?)\]\],ms';
	if (preg_match_all($regexp, $letexte, $matches, PREG_SET_ORDER))
	foreach ($matches as $regs) {
		$note_source = $regs[0];
Yannick Patois's avatar
Yannick Patois a validé
		$note_texte = $regs[1];
		$num_note = false;
Fil's avatar
Fil a validé

		// note auto ou pas ?
		if (preg_match(",^ *<([^>]*)>,", $note_texte, $regs)){
			$num_note = $regs[1];
			$note_texte = str_replace($regs[0], "", $note_texte);
Fil's avatar
Fil a validé
		} else {
Yannick Patois's avatar
Yannick Patois a validé
			$compt_note++;
			$num_note = $compt_note;
Yannick Patois's avatar
Yannick Patois a validé
		}
Fil's avatar
Fil a validé

		// preparer la note
			if ($marqueur_notes) // quand il y a plusieurs series
								 // de notes sur une meme page
			$ancre = $mn.urlencode($num_note);

			// creer le popup 'title' sur l'appel de note
			if ($title = supprimer_tags(propre($note_texte))) {
				$title = $ouvre_note.$ancre.$ferme_note.$title;
				$title = ' title="<html>'
				. texte_backend(couper($title,80)).'</html>"';
			}

			$insert = "$ouvre_ref<a href=\"#nb$ancre\" name=\"nh$ancre\" class=\"spip_note\"$title>$num_note</a>$ferme_ref";
ARNO*'s avatar
ARNO* a validé
			$appel = "<html>$ouvre_note<a href=\"#nh$ancre\" name=\"nb$ancre\" class=\"spip_note\">$num_note</a>$ferme_note</html>";
Yannick Patois's avatar
Yannick Patois a validé
		} else {
			$insert = '';
Fil's avatar
Fil a validé
			$appel = '';
Yannick Patois's avatar
Yannick Patois a validé
		}
Fil's avatar
Fil a validé

		// l'ajouter "brut" dans les notes
		if ($note_texte) {
			if ($mes_notes)
				$mes_notes .= "\n\n";
Fil's avatar
Fil a validé
			$mes_notes .= $appel . $note_texte;
		}

		// dans le texte, mettre l'appel de note a la place de la note
		$pos = strpos($letexte, $note_source);
		$letexte = substr($letexte, 0, $pos) . $insert
			. substr($letexte, $pos + strlen($note_source));
Yannick Patois's avatar
Yannick Patois a validé
	}

Antoine Pitrou's avatar
Antoine Pitrou a validé
	//
	// Raccourcis automatiques [?SPIP] vers un glossaire
Antoine Pitrou's avatar
Antoine Pitrou a validé
	// (on traite ce raccourci en deux temps afin de ne pas appliquer
	//  la typo sur les URLs, voir raccourcis liens ci-dessous)
	//
	if ($url_glossaire_externe) {
		$regexp = "|\[\?+([^][<>]+)\]|";
		if (preg_match_all($regexp, $letexte, $matches, PREG_SET_ORDER))
		foreach ($matches as $regs) {
Antoine Pitrou's avatar
Antoine Pitrou a validé
			$terme = trim($regs[1]);
			$terme_underscore = urlencode(preg_replace(',\s+,', '_', $terme));
Fil's avatar
Fil a validé
			if (strstr($url_glossaire_externe,"%s"))
				$url = str_replace("%s", $terme_underscore, $url_glossaire_externe);
Fil's avatar
Fil a validé
			else
				$url = $url_glossaire_externe.$terme_underscore;
			$url = str_replace("@lang@", $GLOBALS['spip_lang'], $url);
Fil's avatar
Fil a validé
			$code = '['.$terme.'->?'.$url.']';
Antoine Pitrou's avatar
Antoine Pitrou a validé
			$letexte = str_replace($regs[0], $code, $letexte);
		}
	}

	//
	// Raccourcis liens [xxx->url] (cf. fonction extraire_lien ci-dessus)
	// Note : complique car c'est ici qu'on applique la typo() !
Yannick Patois's avatar
Yannick Patois a validé
	//
Fil's avatar
Fil a validé
	$regexp = "|\[([^][]*)->(>?)([^]]*)\]|ms";
	$inserts = array();
	if (preg_match_all($regexp, $letexte, $matches, PREG_SET_ORDER)) {
		$i = 0;
		foreach ($matches as $regs) {
			list($insert) = extraire_lien($regs);
			$inserts[++$i] = $insert;
			$letexte = str_replace($regs[0], "@@SPIP_ECHAPPE$i@@", $letexte);
		}
	}
	$letexte = typo($letexte);
	foreach ($inserts as $i => $insert) {
		$letexte = str_replace("@@SPIP_ECHAPPE$i@@", $insert, $letexte);
Yannick Patois's avatar
Yannick Patois a validé
	}
Yannick Patois's avatar
Yannick Patois a validé
	//
	// Tableaux
	//

	// traiter le cas particulier des echappements (<doc...> par exemple)
	// qui auraient provoque des \n\n</no p> devant les | des tableaux
	$letexte = preg_replace(',[|]\n\n</no p>@@,','|@@', $letexte);
	$letexte = preg_replace(',@@<no p>\n\n[|],','@@|', $letexte);

	// ne pas oublier les tableaux au debut ou a la fin du texte
Fil's avatar
Fil a validé
	$letexte = preg_replace(",^\n?[|],", "\n\n|", $letexte);
	$letexte = preg_replace(",\n\n+[|],", "\n\n\n\n|", $letexte);
	$letexte = preg_replace(",[|](\n\n+|\n?$),", "|\n\n\n\n", $letexte);

	// traiter chaque tableau
	if (preg_match_all(',[^|](\n[|].*[|]\n)[^|],Ums', $letexte,
Fil's avatar
Fil a validé
	$regs, PREG_SET_ORDER))
	foreach ($regs as $tab) {
		$letexte = str_replace($tab[1], traiter_tableau($tab[1]), $letexte);
Yannick Patois's avatar
Yannick Patois a validé
	}
Yannick Patois's avatar
Yannick Patois a validé
	//
	// Ensemble de remplacements implementant le systeme de mise
	// en forme (paragraphes, raccourcis...)
	//

	$letexte = "\n".trim($letexte);
	if (ereg("\n-[*#]", $letexte))
		$letexte = traiter_listes($letexte);
	$cherche1 = array(
		/* 0 */ 	"/\n(----+|____+)/",
		/* 1 */ 	"/\n-- */",
		/* 2 */ 	"/\n- */",
		/* 3 */ 	"/\n_ +/",
		/* 4 */ 	"/[{][{][{]/",
		/* 5 */ 	"/[}][}][}]/",
		/* 6 */ 	"/(( *)\n){2,}(<br[[:space:]]*\/?".">)?/",
		/* 7 */ 	"/[{][{]/",
		/* 8 */ 	"/[}][}]/",
		/* 9 */ 	"/[{]/",
		/* 10 */	"/[}]/",
		/* 11 */	"/(<br[[:space:]]*\/?".">){2,}/",
		/* 12 */	"/<p>([\n]*)(<br[[:space:]]*\/?".">)+/",
		/* 13 */	"/<p>/",
		/* 14 		"/\n/", */
		/* 15 */	"/<quote>/",
		/* 16 */	"/<\/quote>/"
	);
	$remplace1 = array(
		/* 0 */ 	"\n\n$ligne_horizontale\n\n",
		/* 1 */ 	"\n<br />&mdash;&nbsp;",
		/* 2 */ 	"\n<br />$puce&nbsp;",
		/* 3 */ 	"\n<br />",
		/* 4 */ 	"\n\n$debut_intertitre",
		/* 5 */ 	"$fin_intertitre\n\n",
Fil's avatar
Fil a validé
		/* 6 */ 	"<p class=\"spip\">",
Fil's avatar
Fil a validé
		/* 7 */ 	"<strong class=\"spip\">",
		/* 8 */ 	"</strong>",
		/* 9 */ 	"<i class=\"spip\">",
		/* 10 */	"</i>",
		/* 11 */	"<p class=\"spip\">",
		/* 12 */	"<p class=\"spip\">",
		/* 13 */	"<p class=\"spip\">",
		/* 14 		" ", */
Fil's avatar
Fil a validé
		/* 15 */	"<blockquote class=\"spip\"><p class=\"spip\">",
		/* 16 */	"</blockquote><p class=\"spip\">"
	);
	$letexte = preg_replace($cherche1, $remplace1, $letexte);
	$letexte = preg_replace("@^ <br />@", "", $letexte);
Yannick Patois's avatar
Yannick Patois a validé

	// Installer les images et documents
	if (preg_match_all(__preg_img, $letexte, $matches, PREG_SET_ORDER)) {
		include_ecrire("inc_documents");
		$letexte = inserer_documents($letexte, $matches);
	}
	// 1. Ajouter le paragraphe initial s'il y a lieu
	if (strpos(' '.$letexte, '<p class="spip">'))
		$letexte = '<p class="spip">'.$letexte;

	// 2. preserver les balises-bloc
	$blocs = 'div|pre|ul|li|blockquote|h[1-5r]|table|center|'
Fil's avatar
Fil a validé
		.'tr|td|th|tbody|tfoot|form|object';