Changement de la gestion des URL spéciales # # 3.2.1 # Olivier # => Changement syntaxe des macros # # 3.2 # Olivier # => Changement de fonctionnement des macros # => Passage de fonctions externes pour les macros et les mots wiki # # 3.1d # Jérôme Lipowicz # => antispam # Olivier # => centrage d'image # # 3.1c # Olivier # => Possibilité d'échaper les | dans les marqueurs avec \ # # 3.1b # Nicolas Chachereau # => Changement de regexp pour la correction syntaxique # # 3.1a # Olivier # => Bug du Call-time pass-by-reference # # 3.1 # Olivier # => Ajout des macros «««..»»» # => Ajout des blocs vides øøø # => Ajout du niveau de titre paramétrable # => Option de blocage du parseur dans les
#			=> Titres au format setext (experimental, désactivé)
#
# 3.0
# Olivier		=> Récriture du parseur inline, plus d'erreur XHTML
#			=> Ajout d'une vérification d'intégrité pour les listes
#			=> Les acronymes sont maintenant dans un fichier texte
#			=> Ajout d'un tag images ((..)), del --..-- et ins ++..++
#			=> Plus possible de faire des liens JS [lien|javascript:...]
#			=> Ajout des notes de bas de page §§...§§
#			=> Ajout des mots wiki
#
# 2.5
# Olivier		=> Récriture du code, plus besoin du saut de ligne entre blocs !=
#
# 2.0
# Stephanie	=> correction des PCRE et ajout de fonctionnalités
# Mathieu 	=> ajout du strip-tags, implementation des options, reconnaissance automatique d'url, etc.
# Olivier		=> chagement de active_link en active_urls
#			=> ajout des options pour les blocs
#			=> intégration de l'aide dans le code, avec les options
#			=> début de quelque chose pour la reconnaissance auto d'url (avec Mat)

# TODO :
# Mathieu	=> active_wiki_urls (modifier wikiParseUrl ?)
# 		=> active_auto_urls
#
# *		=> ajouter des options.
# 		=> trouver un meilleur nom pour active_link ? (pour le jour ou ca sera tellement une usine
#		   a gaz que on generera des tags  :)
#

# Wiki2xhtml

class wiki2xhtmlBasic
{
	var $__version__ = '3.2.2';
	
	var $T;
	var $opt;
	var $line;
	var $acro_table;
	var $foot_notes;
	var $macros;
	var $functions;
	
	var $tags;
	var $open_tags;
	var $close_tags;
	var $all_tags;
	var $tag_pattern;
	var $escape_table;
	var $allowed_inline = array();
	
	function wiki2xhtml()
	{
		# Mise en place des options
		$this->setOpt('active_title',1);		# Activation des titres !!!
		$this->setOpt('active_setext_title',0);	# Activation des titres setext (EXPERIMENTAL)
		$this->setOpt('active_hr',1);			# Activation des 
$this->setOpt('active_lists',1); # Activation des listes $this->setOpt('active_quote',1); # Activation du
$this->setOpt('active_pre',1); # Activation du
		$this->setOpt('active_empty',1);		# Activation du bloc vide øøø
		$this->setOpt('active_auto_urls',0);	# Activation de la reconnaissance d'url (inactif)
		$this->setOpt('active_autoemails',0);	# Activation de la reconnaissance des emails (inactif)
		$this->setOpt('active_antispam',1);     # Activation de l'antispam pour les emails
		$this->setOpt('active_urls',1);		# Activation des liens []
		$this->setOpt('active_auto_img',1);	# Activation des images automatiques dans les liens []
		$this->setOpt('active_img',1);		# Activation des images (())
		$this->setOpt('active_anchor',1);		# Activation des ancres ~...~
		$this->setOpt('active_em',1);			# Activation du  ''...''
		$this->setOpt('active_strong',1);		# Activation du  __...__
		$this->setOpt('active_br',1);			# Activation du 
%%% $this->setOpt('active_q',1); # Activation du {{...}} $this->setOpt('active_code',1); # Activation du @@...@@ $this->setOpt('active_acronym',1); # Activation des acronymes $this->setOpt('active_ins',1); # Activation des ins ++..++ $this->setOpt('active_del',1); # Activation des del --..-- $this->setOpt('active_footnotes',1); # Activation des notes de bas de page $this->setOpt('active_wikiwords',0); # Activation des mots wiki $this->setOpt('active_macros',1); # Activation des macros {{{ }}} $this->setOpt('parse_pre',1); # Parser l'intérieur de blocs
 ?
		
		$this->setOpt('active_fix_word_entities',1); # Fixe les caractères MS
		$this->setOpt('active_fr_syntax',1);	# Corrections syntaxe FR
		
		$this->setOpt('first_title_level',3);	# Premier niveau de titre 
		
		$this->setOpt('note_prefix','wiki-footnote');
		$this->setOpt('note_str','

Notes

%s
'); $this->setOpt('words_pattern','((?setOpt('mail_pattern','/^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$/'); $this->setOpt('acronyms_file',dirname(__FILE__).'/acronyms.txt'); $this->acro_table = $this->__getAcronyms(); $this->foot_notes = array(); $this->functions = array(); $this->macros = array(); $this->registerFunction('macro:html',array($this,'__macroHTML')); } function setOpt($option, $value) { $this->opt[$option] = $value; } function getOpt($option) { return (!empty($this->opt[$option])) ? $this->opt[$option] : false; } function registerFunction($type,$name) { if (is_callable($name)) { $this->functions[$type] = $name; } else { trigger_error('Wiki2xhtml : Function does not exist', E_USER_NOTICE); } } function transform($in) { # Initialisation des tags $this->__initTags(); $this->foot_notes = array(); # Récupération des macros if ($this->getOpt('active_macros')) { $in = preg_replace('#^///(.*?)///($|\r)#mse',"\\\$this->__getMacro('\\1')",$in); } # Vérification du niveau de titre if ($this->getOpt('first_title_level') > 4) { $this->setOpt('first_title_level',4); } $res = str_replace("\r", '', $in); $escape_pattern = array(); # traitement des titres à la setext if ($this->getOpt('active_setext_title') && $this->getOpt('active_title')) { $res = preg_replace('/^(.*)\n[=]{5,}$/m','!!!$1',$res); $res = preg_replace('/^(.*)\n[-]{5,}$/m','!!$1',$res); } # Transformation des mots Wiki if ($this->getOpt('active_wikiwords') && $this->getOpt('words_pattern')) { $res = preg_replace('/'.$this->getOpt('words_pattern').'/ms','¶¶¶$1¶¶¶',$res); } $this->T = explode("\n",$res); $this->T[] = ''; # Parse les blocs $res = $this->__parseBlocks(); # Line break if ($this->getOpt('active_br')) { $res = preg_replace('/(?', $res); $escape_pattern[] = '%%%'; } # Correction des caractères faits par certains traitement # de texte comme Word if ($this->getOpt('active_fix_word_entities')) { $wR = array( '‚' => '‚', 'ƒ' => 'ƒ', '„' => '„', '…' => '…', '†' => '†', '‡' => '‡', 'ˆ' => 'ˆ', '‰' => '‰', 'Š' => 'Š', '‹' => '‹', 'Œ' => 'Œ', '‘' => '‘', '’' => '’', '“' => '“', '”' => '”', '•' => '•', '–' => '–', '—' => '—', '˜' => '˜', '™' => '™', 'š' => 'š', '›' => '›', 'œ' => 'œ', 'Ÿ' => 'Ÿ', '€' => '€'); $res = str_replace(array_keys($wR),array_values($wR),$res); } # Nettoyage des \s en trop $res = preg_replace('/([\s]+)(<\/p>|<\/li>|<\/pre>)/', '$2', $res); $res = preg_replace('/(
  • )([\s]+)/', '$1', $res); # On vire les escapes $res = preg_replace('/\\\('.implode('|',$escape_pattern).')/','$1',$res); # On vire les ¶¶¶MotWiki¶¶¶ qui sont resté (dans les url...) if ($this->getOpt('active_wikiwords') && $this->getOpt('words_pattern')) { $res = preg_replace('/¶¶¶'.$this->getOpt('words_pattern').'¶¶¶/msU','$1',$res); } # On remet les macros if ($this->getOpt('active_macros')) { $res = preg_replace('/^##########MACRO#([0-9]+)#$/mse','\$this->__putMacro("$1")',$res); } # On ajoute les notes if (count($this->foot_notes) > 0) { $res_notes = ''; $i = 1; foreach ($this->foot_notes as $k => $v) { $res_notes .= "\n".'

    ['.$i.'] '.$v.'

    '; $i++; } $res .= sprintf("\n".$this->getOpt('note_str')."\n",$res_notes); } return $res; } /* PRIVATE --------------------------------------------------- */ function __initTags() { $this->tags = array( 'em' => array("''","''"), 'strong' => array('__','__'), 'acronym' => array('??','??'), 'a' => array('[',']'), 'img' => array('((','))'), 'q' => array('{{','}}'), 'code' => array('@@','@@'), 'anchor' => array('~','~'), 'del' => array('--','--'), 'ins' => array('++','++'), 'note' => array('$$','$$'), 'word' => array('¶¶¶','¶¶¶') ); # Suppression des tags selon les options if (!$this->getOpt('active_urls')) { unset($this->tags['a']); } if (!$this->getOpt('active_img')) { unset($this->tags['img']); } if (!$this->getOpt('active_anchor')) { unset($this->tags['anchor']); } if (!$this->getOpt('active_em')) { unset($this->tags['em']); } if (!$this->getOpt('active_strong')) { unset($this->tags['strong']); } if (!$this->getOpt('active_q')) { unset($this->tags['q']); } if (!$this->getOpt('active_code')) { unset($this->tags['code']); } if (!$this->getOpt('active_acronym')) { unset($this->tags['acronym']); } if (!$this->getOpt('active_ins')) { unset($this->tags['ins']); } if (!$this->getOpt('active_del')) { unset($this->tags['del']); } if (!$this->getOpt('active_footnotes')) { unset($this->tags['note']); } if (!$this->getOpt('active_wikiwords')) { unset($this->tags['word']); } $this->open_tags = $this->__getTags(); $this->close_tags = $this->__getTags(false); $this->all_tags = $this->__getAllTags(); $this->tag_pattern = $this->__getTagsPattern(); $this->escape_table = $this->all_tags; array_walk($this->escape_table,create_function('&$a','$a = \'\\\\\'.$a;')); } function __getTags($open=true) { $res = array(); foreach ($this->tags as $k => $v) { $res[$k] = ($open) ? $v[0] : $v[1]; } return $res; } function __getAllTags() { $res = array(); foreach ($this->tags as $v) { $res[] = $v[0]; $res[] = $v[1]; } return array_values(array_unique($res)); } function __getTagsPattern($escape=false) { $res = $this->all_tags; array_walk($res,create_function('&$a','$a = preg_quote($a,"/");')); if (!$escape) { return '/(?T); for ($i=0; $i<$max; $i++) { $pre_mode = $mode; $pre_type = $type; $end = ($i+1 == $max); $line = $this->__getLine($i,$type,$mode); if ($type != 'pre' || $this->getOpt('parse_pre')) { $line = $this->__inlineWalk($line); } $res .= $this->__closeLine($type,$mode,$pre_type,$pre_mode); $res .= $this->__openLine($type,$mode,$pre_type,$pre_mode); # P dans les blockquotes if ($type == 'blockquote' && trim($line) == '' && $pre_type == $type) { $res .= "

    \n

    "; } # Correction de la syntaxe FR dans tous sauf pre et hr # Sur idée de Christophe Bonijol # Changement de regex (Nicolas Chachereau) if ($this->getOpt('active_fr_syntax') && $type != NULL && $type != 'pre' && $type != 'hr') { $line = preg_replace('/[ ]+([:?!;](\s|$))/',' $1',$line); $line = preg_replace('/[ ]+(»)/',' $1',$line); $line = preg_replace('/(«)[ ]+/','$1 ',$line); } $res .= $line; } return trim($res); } function __getLine($i,&$type,&$mode) { $pre_type = $type; $pre_mode = $mode; $type = $mode = NULL; if (empty($this->T[$i])) { return false; } $line = htmlspecialchars($this->T[$i],ENT_NOQUOTES); # Ligne vide if (empty($line)) { $type = NULL; } elseif ($this->getOpt('active_empty') && preg_match('/^øøø(.*)$/',$line,$cap)) { $type = NULL; $line = trim($cap[1]); } # Titre elseif ($this->getOpt('active_title') && preg_match('/^([!]{1,4})(.*)$/',$line,$cap)) { $type = 'title'; $mode = strlen($cap[1]); $line = trim($cap[2]); } # Ligne HR elseif ($this->getOpt('active_hr') && preg_match('/^[-]{4}[- ]*$/',$line)) { $type = 'hr'; $line = NULL; } # Blockquote elseif ($this->getOpt('active_quote') && preg_match('/^(>|;:)(.*)$/',$line,$cap)) { $type = 'blockquote'; $line = trim($cap[2]); } # Liste elseif ($this->getOpt('active_lists') && preg_match('/^([*#]+)(.*)$/',$line,$cap)) { $type = 'list'; $mode = $cap[1]; $valid = true; # Vérification d'intégrité $dl = ($type != $pre_type) ? 0 : strlen($pre_mode); $d = strlen($mode); $delta = $d-$dl; if ($delta < 0 && strpos($pre_mode,$mode) !== 0) { $valid = false; } if ($delta > 0 && $type == $pre_type && strpos($mode,$pre_mode) !== 0) { $valid = false; } if ($delta == 0 && $mode != $pre_mode) { $valid = false; } if ($delta > 1) { $valid = false; } if (!$valid) { $type = 'p'; $mode = NULL; $line = '
    '.$line; } else { $line = trim($cap[2]); } } # Préformaté elseif ($this->getOpt('active_pre') && preg_match('/^[ ]{1}(.*)$/',$line,$cap)) { $type = 'pre'; $line = $cap[1]; } # Paragraphe else { $type = 'p'; $line = trim($line); } return $line; } function __openLine($type,$mode,$pre_type,$pre_mode) { $open = ($type != $pre_type); if ($open && $type == 'p') { return "\n

    "; } elseif ($open && $type == 'blockquote') { return "\n

    "; } elseif (($open || $mode != $pre_mode) && $type == 'title') { $fl = $this->getOpt('first_title_level'); $fl = $fl+3; $l = $fl-$mode; return "\n'; } elseif ($open && $type == 'pre') { return "\n

    ";
    		}
    		elseif ($open && $type == 'hr')
    		{
    			return "\n
    "; } elseif ($type == 'list') { $dl = ($open) ? 0 : strlen($pre_mode); $d = strlen($mode); $delta = $d-$dl; $res = ''; if($delta > 0) { if(substr($mode, -1, 1) == '*') { $res .= "
      \n"; } else { $res .= "
        \n"; } } elseif ($delta < 0) { $res .= "\n"; for($j = 0; $j < abs($delta); $j++) { if (substr($pre_mode,(0 - $j - 1), 1) == '*') { $res .= "
    \n
  • \n"; } else { $res .= "\n\n"; } } } else { $res .= "\n"; } return $res."
  • "; } else { return NULL; } } function __closeLine($type,$mode,$pre_type,$pre_mode) { $close = ($type != $pre_type); if ($close && $pre_type == 'p') { return "

    \n"; } elseif ($close && $pre_type == 'blockquote') { return "

  • \n"; } elseif (($close || $mode != $pre_mode) && $pre_type == 'title') { $fl = $this->getOpt('first_title_level'); $fl = $fl+3; $l = $fl-$pre_mode; return '\n"; } elseif ($close && $pre_type == 'pre') { return "
    \n"; } elseif ($close && $pre_type == 'list') { $res = ''; for($j = 0; $j < strlen($pre_mode); $j++) { if(substr($pre_mode,(0 - $j - 1), 1) == '*') { $res .= "\n"; } else { $res .= "\n"; } } return $res; } else { return "\n"; } } /* Inline --------------------------------------------------- */ function __inlineWalk($str,$allow_only=NULL) { $tree = preg_split($this->tag_pattern,$str,-1,PREG_SPLIT_DELIM_CAPTURE); $res = ''; for ($i=0; $iopen_tags)) && ($allow_only == NULL || in_array(array_search($tree[$i],$this->open_tags),$allow_only))) { $tag = array_search($tree[$i],$this->open_tags); $tag_type = 'open'; if (($tidy = $this->__makeTag($tree,$tag,$i,$i,$attr,$tag_type)) !== false) { if ($tag != '') { $res .= '<'.$tag.$attr; $res .= ($tag_type == 'open') ? '>' : ' />'; } $res .= $tidy; } else { $res .= $tree[$i]; } } else { $res .= $tree[$i]; } } # Suppression des echappements $res = str_replace($this->escape_table,$this->all_tags,$res); return $res; } function __makeTag(&$tree,&$tag,$position,&$j,&$attr,&$type) { $res = ''; $closed = false; $itag = $this->close_tags[$tag]; # Recherche fermeture for ($i=$position+1;$i__parseLink($res,$tag,$attr,$type); break; case 'img': $type = 'close'; $res = $this->__parseImg($res,$attr); break; case 'acronym': $res = $this->__parseAcronym($res,$attr); break; case 'q': $res = $this->__parseQ($res,$attr); break; case 'anchor': $tag = 'a'; $res = $this->__parseAnchor($res,$attr); break; case 'note': $tag = ''; $res = $this->__parseNote($res); break; case 'word': $res = $this->parseWikiWord($res,$tag,$attr,$type); break; default : $res = $this->__inlineWalk($res); break; } if ($type == 'open' && $tag != '') { $res .= ''; } $j = $i; break; } } return $res; } else { return false; } } function __splitTagsAttr($str) { $res = preg_split('/(? $v) { $res[$k] = str_replace("\|",'|',$v); } return $res; } # Antispam (Jérôme Lipowicz) function __antiSpam($str) { $encoded = bin2hex($str); $encoded = chunk_split($encoded, 2, '%'); $encoded = '%'.substr($encoded, 0, strlen($encoded) - 1); return $encoded; } function __parseLink($str,&$tag,&$attr,&$type) { $n_str = $this->__inlineWalk($str,array('acronym','img')); $data = $this->__splitTagsAttr($n_str); $no_image = false; if (count($data) == 1) { $url = trim($str); $content = $str; $lang = ''; $title = ''; } elseif (count($data) > 1) { $url = trim($data[1]); $content = $data[0]; $lang = (!empty($data[2])) ? $this->protectAttr($data[2],true) : ''; $title = (!empty($data[3])) ? $data[3] : ''; $no_image = (!empty($data[4])) ? (boolean) $data[4] : false; } # Remplacement si URL spéciale $this->__specialUrls($url,$content,$lang,$title); # On vire les   dans l'url $url = str_replace(' ',' ',$url); if (ereg('^(.+)[.](gif|jpg|jpeg|png)$', $url) && !$no_image && $this->getOpt('active_auto_img')) { # On ajoute les dimensions de l'image si locale # Idée de Stephanie $img_size = NULL; if (!ereg('[a-zA-Z]+://', $url)) { if (ereg('^/',$url)) { $path_img = $_SERVER['DOCUMENT_ROOT'] . $url; } else { $path_img = $url; } $img_size = @getimagesize($path_img); } $attr = ' src="'.$this->protectAttr($this->protectUrls($url)).'"'. $attr .= (count($data) > 1) ? ' alt="'.$this->protectAttr($content).'"' : ' alt=""'; $attr .= ($lang) ? ' lang="'.$lang.'"' : ''; $attr .= ($title) ? ' title="'.$this->protectAttr($title).'"' : ''; $attr .= (is_array($img_size)) ? ' '.$img_size[3] : ''; $tag = 'img'; $type = 'close'; return NULL; } else { if ($this->getOpt('active_antispam') && preg_match('/^mailto:/',$url)) { $url = 'mailto:'.$this->__antiSpam(substr($url,7)); } $attr = ' href="'.$this->protectAttr($this->protectUrls($url)).'"'; $attr .= ($lang) ? ' hreflang="'.$lang.'"' : ''; $attr .= ($title) ? ' title="'.$this->protectAttr($title).'"' : ''; return $content; } } function __getSpecialUrls() { $res = array(); foreach ($this->functions as $k => $v) { if (strpos($k,'url:') === 0) { $res[substr($k,4)] = $v; } } var_dump($res); } function __specialUrls(&$url,&$content,&$lang,&$title) { foreach ($this->functions as $k => $v) { if (strpos($k,'url:') === 0 && strpos($url,substr($k,4)) === 0) { $res = call_user_func($v,$url,$content); $url = isset($res['url']) ? $res['url'] : $url; $content = isset($res['content']) ? $res['content'] : $content; $lang = isset($res['lang']) ? $res['lang'] : $lang; $title = isset($res['title']) ? $res['title'] : $title; break; } } } function __parseImg($str,&$attr) { $data = $this->__splitTagsAttr($str); $alt = ''; $url = $data[0]; if (!empty($data[1])) { $alt = $data[1]; } $attr = ' src="'.$this->protectAttr($this->protectUrls($url)).'"'; $attr .= ' alt="'.$this->protectAttr($alt).'"'; if (!empty($data[2])) { $data[2] = strtoupper($data[2]); if ($data[2] == 'G' || $data[2] == 'L') { $attr .= ' style="float:left; margin: 0 1em 1em 0;"'; } elseif ($data[2] == 'D' || $data[2] == 'R') { $attr .= ' style="float:right; margin: 0 0 1em 1em;"'; } elseif ($data[2] == 'C') { $attr .= ' style="display:block; margin:0 auto;"'; } } if (!empty($data[3])) { $attr .= ' longdesc="'.$this->protectAttr($data[3]).'"'; } return NULL; } function __parseQ($str,&$attr) { $str = $this->__inlineWalk($str); $data = $this->__splitTagsAttr($str); $content = $data[0]; $lang = (!empty($data[1])) ? $this->protectAttr($data[1],true) : ''; $attr .= (!empty($lang)) ? ' lang="'.$lang.'"' : ''; $attr .= (!empty($data[2])) ? ' cite="'.$this->protectAttr($data[2]).'"' : ''; return $content; } function __parseAnchor($str,&$attr) { $name = $this->protectAttr($str,true); if ($name != '') { $attr = ' name="'.$name.'"'; } return null; } function __parseNote($str) { $i = count($this->foot_notes)+1; $id = $this->getOpt('note_prefix').'-'.$i; $this->foot_notes[$id] = $this->__inlineWalk($str); return '\['.$i.'\]'; } # Obtenir un acronyme function __parseAcronym($str,&$attr) { $data = $this->__splitTagsAttr($str); $acronym = $data[0]; $title = $lang = ''; if (count($data) > 1) { $title = $data[1]; $lang = (!empty($data[2])) ? $this->protectAttr($data[2],true) : ''; } if ($title == '' && !empty($this->acro_table[$acronym])) { $title = $this->acro_table[$acronym]; } $attr = ($title) ? ' title="'.$this->protectAttr($title).'"' : ''; $attr .= ($lang) ? ' lang="'.$lang.'"' : ''; return $acronym; } # Définition des acronymes, dans le fichier acronyms.txt function __getAcronyms() { $file = $this->getOpt('acronyms_file'); $res = array(); if (file_exists($file)) { if (($fc = @file($file)) !== false) { foreach ($fc as $v) { $v = trim($v); if ($v != '') { $p = strpos($v,':'); $K = (string) trim(substr($v,0,$p)); $V = (string) trim(substr($v,($p+1))); if ($K) { $res[$K] = $V; } } } } } return $res; } # Mots wiki (pour héritage) function parseWikiWord($str,&$tag,&$attr,&$type) { $tag = $attr = ''; if (isset($this->functions['wikiword'])) { return call_user_func($this->functions['wikiword'],$str); } return $str; } /* Protection des attributs */ function protectAttr($str,$name=false) { if ($name && !preg_match('/^[A-Za-z][A-Za-z0-9_:.-]*$/',$str)) { return ''; } return str_replace(array("'",'"'),array(''','"'),$str); } /* Protection des urls */ function protectUrls($str) { if (preg_match('/^javascript:/',$str)) { $str = '#'; } return $str; } /* Macro --------------------------------------------------- */ function __getMacro($s) { $this->macros[] = str_replace('\"','"',$s); return 'øøø##########MACRO#'.(count($this->macros)-1).'#'; } function __putMacro($id) { $id = (integer) $id; if (isset($this->macros[$id])) { $content = str_replace("\r",'',$this->macros[$id]); $c = explode("\n",$content); # première ligne, premier mot $fl = trim($c[0]); $fw = $fl; if ($fl) { if (strpos($fl,' ') !== false) { $fw = substr($fl,0,strpos($fl,' ')); } $content = implode("\n",array_slice($c,1)); } if ($c[0] == "\n") { $content = implode("\n",array_slice($c,1)); } if ($fw) { if (isset($this->functions['macro:'.$fw])) { return call_user_func($this->functions['macro:'.$fw],$content,$fl); } } # Si on n'a rien pu faire, on retourne le tout sous # forme de
    			return '
    '.htmlspecialchars($this->macros[$id]).'
    '; } return null; } function __macroHTML($s) { return $s; } /* Aide et debug --------------------------------------------------- */ function help() { $help['b'] = array(); $help['i'] = array(); $help['b'][] = 'Laisser une ligne vide entre chaque bloc de même nature.'; $help['b'][] = 'Paragraphe : du texte et une ligne vide'; if ($this->getOpt('active_title')) { $help['b'][] = 'Titre : !!!, !!, '. '! pour des titres plus ou moins importants'; } if ($this->getOpt('active_hr')) { $help['b'][] = 'Trait horizontal : ----'; } if ($this->getOpt('active_lists')) { $help['b'][] = 'Liste : ligne débutant par * ou '. '#. Il est possible de mélanger les listes '. '(*#*) pour faire des listes de plusieurs niveaux. '. 'Respecter le style de chaque niveau'; } if ($this->getOpt('active_pre')) { $help['b'][] = 'Texte préformaté : espace devant chaque ligne de texte'; } if ($this->getOpt('active_quote')) { $help['b'][] = 'Bloc de citation : > ou '. ';: devant chaque ligne de texte'; } if ($this->getOpt('active_fr_syntax')) { $help['i'][] = 'La correction de ponctuation est active. Un espace '. 'insécable remplacera automatiquement tout espace '. 'précédant les marques ";","?",":" et "!".'; } if ($this->getOpt('active_em')) { $help['i'][] = 'Emphase : deux apostrophes \'\'texte\'\''; } if ($this->getOpt('active_strong')) { $help['i'][] = 'Forte emphase : deux soulignés __texte__'; } if ($this->getOpt('active_br')) { $help['i'][] = 'Retour forcé à la ligne : %%%'; } if ($this->getOpt('active_ins')) { $help['i'][] = 'Insertion : deux plus ++texte++'; } if ($this->getOpt('active_del')) { $help['i'][] = 'Suppression : deux moins --texte--'; } if ($this->getOpt('active_urls')) { $help['i'][] = 'Lien : [url], [nom|url], '. '[nom|url|langue] ou [nom|url|langue|titre].'; $help['i'][] = 'Image : comme un lien mais avec une extension d\'image.'. '
    Pour désactiver la reconnaissance d\'image mettez 0 dans un dernier '. 'argument. Par exemple [image|image.gif||0] fera un lien vers l\'image au '. 'lieu de l\'afficher.'. '
    Il est conseillé d\'utiliser la nouvelle syntaxe.'; } if ($this->getOpt('active_img')) { $help['i'][] = 'Image (nouvelle syntaxe) : '. '((url|texte alternatif)), '. '((url|texte alternatif|position)) ou '. '((url|texte alternatif|position|description longue)). '. '
    La position peut prendre les valeur L ou G (gauche), R ou D (droite) ou C (centré).'; } if ($this->getOpt('active_anchor')) { $help['i'][] = 'Ancre : ~ancre~'; } if ($this->getOpt('active_acronym')) { $help['i'][] = 'Acronyme : ??acronyme?? ou '. '??acronyme|titre??'; } if ($this->getOpt('active_q')) { $help['i'][] = 'Citation : {{citation}}, '. '{{citation|langue}} ou {{citation|langue|url}}'; } if ($this->getOpt('active_code')) { $help['i'][] = 'Code : @@code ici@@'; } if ($this->getOpt('active_footnotes')) { $help['i'][] = 'Note de bas de page : $$Corps de la note$$'; } $res = '
    '; $res .= '
    Blocs
    '; if (count($help['b']) > 0) { $res .= '
    • '; $res .= implode(' ;
    • ', $help['b']); $res .= '.
    '; } $res .= '
    '; $res .= '
    Éléments en ligne
    '; if (count($help['i']) > 0) { $res .= '
    • '; $res .= implode(' ;
    • ', $help['i']); $res .= '.
    '; } $res .= '
    '; $res .= '
    '; return $res; } /* function debug() { $mode = $type = NULL; $max = count($this->T); $res = ''. ''; for ($i=0; $i<$max; $i++) { $pre_mode = $mode; $pre_type = $type; $line = $this->__getLine($i,$type,$mode); $res .= ''. ''; } $res .= '
    p-modep-typemodetypechaine
    '.$pre_mode.''.$pre_type.''.$mode.''.$type.''.$line.'
    '; return $res; } //*/ } ?>