| Current Path : /home/b/o/u/bourgleram/www/398a1/ |
| Current File : /home/b/o/u/bourgleram/www/398a1/engine.tar |
textwheelruleset.php 0000666 00000012043 15252560553 0010706 0 ustar 00 <?php
/*
* TextWheel 0.1
*
* let's reinvent the wheel one last time
*
* This library of code is meant to be a fast and universal replacement
* for any and all text-processing systems written in PHP
*
* It is dual-licensed for any use under the GNU/GPL2 and MIT licenses,
* as suits you best
*
* (c) 2009 Fil - fil@rezo.net
* Documentation & http://zzz.rezo.net/-TextWheel-
*
* Usage: $wheel = new TextWheel(); echo $wheel->text($text);
*
*/
if (!defined('_ECRIRE_INC_VERSION')) return;
require_once dirname(__FILE__)."/textwheelrule.php";
abstract class TextWheelDataSet {
# list of data
protected $data = array();
/**
* file finder : can be overloaded in order to use application dependant
* path find method
*
* @param string $file
* @param string $path
* @return string
*/
protected function findFile(&$file, $path=''){
static $default_path;
// absolute file path ?
if (file_exists($file))
return $file;
// file embed with texwheels, relative to calling ruleset
if ($path AND file_exists($f = $path.$file))
return $f;
// textwheel default path ?
if (!$default_path)
$default_path = dirname(__FILE__).'/../wheels/';
if (file_exists($f = $default_path.$file))
return $f;
return false;
}
/**
* Load a yaml file describing data
* @param string $file
* @param string $default_path
* @return array
*/
protected function loadFile(&$file, $default_path='') {
if (!preg_match(',[.]yaml$,i',$file)
// external rules
OR !$file = $this->findFile($file,$default_path))
return array();
defined('_YAML_EVAL_PHP') || define('_YAML_EVAL_PHP', false);
if (!function_exists('yaml_decode')) {
if (function_exists('include_spip'))
include_spip('inc/yaml-mini');
else
require_once dirname(__FILE__).'/../inc/yaml.php';
}
$dataset = yaml_decode(file_get_contents($file));
if (is_null($dataset))
$dataset = array();
# throw new DomainException('yaml file is empty, unreadable or badly formed: '.$file.var_export($dataset,true));
// if a php file with same name exists
// include it as it contains callback functions
if ($f = preg_replace(',[.]yaml$,i','.php',$file)
AND file_exists($f)) {
$dataset[] = array('require' => $f, 'priority' => -1000);
}
return $dataset;
}
}
class TextWheelRuleSet extends TextWheelDataSet {
# sort flag
protected $sorted = true;
/**
* Constructor
*
* @param array|string $ruleset
* @param string $filepath
*/
public function TextWheelRuleSet($ruleset = array(), $filepath='') {
if ($ruleset)
$this->addRules($ruleset, $filepath);
}
/**
* public static loader
* can be overloaded to use memoization
*
* @param array $ruleset
* @param string $callback
* @param string $class
* @return class
*/
public static function &loader($ruleset, $callback='', $class='TextWheelRuleSet'){
$ruleset = new $class($ruleset);
if ($callback)
$callback($ruleset);
return $ruleset;
}
/**
* Get an existing named rule in order to override it
*
* @param string $name
* @return string
*/
public function &getRule($name){
if (isset($this->data[$name]))
return $this->data[$name];
$result = null;
return $result;
}
/**
* get sorted Rules
* @return array
*/
public function &getRules(){
$this->sort();
return $this->data;
}
/**
* add a rule
*
* @param TextWheelRule $rule
*/
public function addRule($rule) {
# cast array-rule to object
if (is_array($rule))
$rule = new TextWheelRule($rule);
$this->data[] = $rule;
$this->sorted = false;
}
/**
* add an list of rules
* can be
* - an array of rules
* - a string filename
* - an array of string filename
*
* @param array|string $rules
* @param string $filepath
*/
public function addRules($rules, $filepath='') {
// rules can be an array of filename
if (is_array($rules) AND is_string(reset($rules))) {
foreach($rules as $i=>$filename)
$this->addRules($filename);
return;
}
// rules can be a string : yaml filename
if (is_string($rules)) {
$file = $rules; // keep the real filename
$rules = $this->loadFile($file, $filepath);
$filepath = dirname($file).'/';
}
// rules can be an array of rules
if (is_array($rules) AND count($rules)){
# cast array-rules to objects
foreach ($rules as $i => $rule) {
if (is_array($rule))
$rules[$i] = new TextWheelRule($rule);
// load subwheels when necessary
if ($rules[$i]->is_wheel){
// subruleset is of the same class as current ruleset
$class = get_class($this);
$rules[$i]->replace = new $class($rules[$i]->replace, $filepath);
}
}
$this->data = array_merge($this->data, $rules);
$this->sorted = false;
}
}
/**
* Sort rules according to priority and
* purge disabled rules
*
*/
protected function sort() {
if (!$this->sorted) {
$rulz = array();
foreach($this->data as $index => $rule)
if (!$rule->disabled)
$rulz[intval($rule->priority)][$index] = $rule;
ksort($rulz);
$this->data = array();
foreach($rulz as $rules)
$this->data += $rules;
$this->sorted = true;
}
}
}
textwheel.php 0000666 00000035542 15252560553 0007313 0 ustar 00 <?php
/*
* TextWheel 0.1
*
* let's reinvent the wheel one last time
*
* This library of code is meant to be a fast and universal replacement
* for any and all text-processing systems written in PHP
*
* It is dual-licensed for any use under the GNU/GPL2 and MIT licenses,
* as suits you best
*
* (c) 2009 Fil - fil@rezo.net
* Documentation & http://zzz.rezo.net/-TextWheel-
*
* Usage: $wheel = new TextWheel(); echo $wheel->text($text);
*
*/
if (!defined('_ECRIRE_INC_VERSION')) return;
require_once dirname(__FILE__)."/textwheelruleset.php";
class TextWheel {
protected $ruleset;
protected static $subwheel = array();
protected $compiled = array();
/**
* Constructor
* @param TextWheelRuleSet $ruleset
*/
public function TextWheel($ruleset = null) {
$this->setRuleSet($ruleset);
}
/**
* Set RuleSet
* @param TextWheelRuleSet $ruleset
*/
public function setRuleSet($ruleset){
if (!is_object($ruleset))
$ruleset = new TextWheelRuleSet ($ruleset);
$this->ruleset = $ruleset;
}
/**
* Apply all rules of RuleSet to a text
*
* @param string $t
* @return string
*/
public function text($t) {
$rules = & $this->ruleset->getRules();
## apply each in order
foreach ($rules as $name => $rule) #php4+php5
{
$this->apply($rules[$name], $t);
}
#foreach ($this->rules as &$rule) #smarter &reference, but php5 only
# $this->apply($rule, $t);
return $t;
}
private function export($x) {
return addcslashes(var_export($x, true), "\n\r\t");
}
public function compile($b = null) {
$rules = & $this->ruleset->getRules();
## apply each in order
$pre = array();
$comp = array();
foreach ($rules as $name => $rule)
{
$rule->name = $name;
$this->initRule($rule);
if (is_string($rule->replace)
AND isset($this->compiled[$rule->replace])
AND $fun = $this->compiled[$rule->replace]) {
$pre[] = "\n###\n## $name\n###\n" . $fun;
preg_match(',function (\w+),', $fun, $r);
$rule->compilereplace = $r[1]; # ne pas modifier ->replace sinon on casse l'execution...
}
$r = "\t/* $name */\n";
if ($rule->require)
$r .= "\t".'require_once '.TextWheel::export($rule->require).';'."\n";
if ($rule->if_str)
$r .= "\t".'if (strpos($t, '.TextWheel::export($rule->if_str).') === false)'."\n";
if ($rule->if_stri)
$r .= "\t".'if (stripos($t, '.TextWheel::export($rule->if_stri).') === false)'."\n";
if ($rule->if_match)
$r .= "\t".'if (preg_match('.TextWheel::export($rule->if_match).', $t))'."\n";
if ($rule->func_replace !== 'replace_identity') {
$fun = 'TextWheel::'.$rule->func_replace;
switch($fun) {
case 'TextWheel::replace_all_cb':
$fun = $rule->replace; # trim()...
break;
case 'TextWheel::replace_preg':
$fun = 'preg_replace';
break;
case 'TextWheel::replace_str':
$fun = 'str_replace';
break;
case 'TextWheel::replace_preg_cb':
$fun = 'preg_replace_callback';
break;
default:
break;
}
$r .= "\t".'$t = '.$fun.'('.TextWheel::export($rule->match).', '.TextWheel::export($rule->replace).', $t);'."\n";
}
$comp[] = $r;
}
$code = join ("\n", $comp);
$code = 'function '.$b.'($t) {' . "\n". $code . "\n\treturn \$t;\n}\n\n";
$code = join ("\n", $pre) . $code;
return $code;
}
/**
* Get an internal global subwheel
* read acces for annymous function only
*
* @param int $n
* @return TextWheel
*/
public static function &getSubWheel($n){
return TextWheel::$subwheel[$n];
}
/**
* Create SubWheel (can be overriden in debug class)
* @param TextWheelRuleset $rules
* @return TextWheel
*/
protected function &createSubWheel(&$rules){
$tw = new TextWheel($rules);
return $tw;
}
/**
* Initializing a rule a first call
* including file, creating function or wheel
* optimizing tests
*
* @param TextWheelRule $rule
*/
protected function initRule(&$rule){
# language specific
if ($rule->require){
require_once $rule->require;
}
# optimization: strpos or stripos?
if (isset($rule->if_str)) {
if (strtolower($rule->if_str) !== strtoupper($rule->if_str)) {
$rule->if_stri = $rule->if_str;
unset($rule->if_str);
}
}
if ($rule->create_replace){
$compile = $rule->replace.'($t)';
$rule->replace = create_function('$m', $rule->replace);
$this->compiled[$rule->replace] = $compile;
$rule->create_replace = false;
$rule->is_callback = true;
}
elseif ($rule->is_wheel){
$n = count(TextWheel::$subwheel);
TextWheel::$subwheel[] = $this->createSubWheel($rule->replace);
$var = '$m['.intval($rule->pick_match).']';
if ($rule->type=='all' OR $rule->type=='str' OR $rule->type=='split' OR !isset($rule->match))
$var = '$m';
$code = 'return TextWheel::getSubWheel('.$n.')->text('.$var.');';
$rule->replace = create_function('$m', $code);
$cname = 'compiled_'.str_replace('-','_', $rule->name);
$compile = TextWheel::getSubWheel($n)->compile($cname);
$this->compiled[$rule->replace] = $compile;
$rule->is_wheel = false;
$rule->is_callback = true;
}
# optimization
$rule->func_replace = '';
if (isset($rule->replace)) {
switch($rule->type) {
case 'all':
$rule->func_replace = 'replace_all';
break;
case 'str':
$rule->func_replace = 'replace_str';
// test if quicker strtr usable
if (!$rule->is_callback
AND is_array($rule->match) AND is_array($rule->replace)
AND $c = array_map('strlen',$rule->match)
AND $c = array_unique($c)
AND count($c)==1
AND reset($c)==1
AND $c = array_map('strlen',$rule->replace)
AND $c = array_unique($c)
AND count($c)==1
AND reset($c)==1
){
$rule->match = implode('',$rule->match);
$rule->replace = implode('',$rule->replace);
$rule->func_replace = 'replace_strtr';
}
break;
case 'split':
$rule->func_replace = 'replace_split';
$rule->match = array($rule->match, is_null($rule->glue)?$rule->match:$rule->glue);
break;
case 'preg':
default:
$rule->func_replace = 'replace_preg';
break;
}
if ($rule->is_callback)
$rule->func_replace .= '_cb';
}
if (!method_exists("TextWheel", $rule->func_replace)){
$rule->disabled = true;
$rule->func_replace = 'replace_identity';
}
# /end
}
/**
* Apply a rule to a text
*
* @param TextWheelRule $rule
* @param string $t
* @param int $count
*/
protected function apply(&$rule, &$t, &$count=null) {
if ($rule->disabled)
return;
if (isset($rule->if_chars) AND (strpbrk($t, $rule->if_chars) === false))
return;
if (isset($rule->if_match) AND !preg_match($rule->if_match, $t))
return;
// init rule before testing if_str / if_stri as they are optimized by initRule
if (!isset($rule->func_replace))
$this->initRule($rule);
if (isset($rule->if_str) AND strpos($t, $rule->if_str) === false)
return;
if (isset($rule->if_stri) AND stripos($t, $rule->if_stri) === false)
return;
$func = $rule->func_replace;
TextWheel::$func($rule->match,$rule->replace,$t,$count);
}
/**
* No Replacement function
* fall back in case of unknown method for replacing
* should be called max once per rule
*
* @param mixed $match
* @param mixed $replace
* @param string $t
* @param int $count
*/
protected static function replace_identity(&$match,&$replace,&$t,&$count){
}
/**
* Static replacement of All text
* @param mixed $match
* @param mixed $replace
* @param string $t
* @param int $count
*/
protected static function replace_all(&$match,&$replace,&$t,&$count){
# special case: replace $0 with $t
# replace: "A$0B" will surround the string with A..B
# replace: "$0$0" will repeat the string
if (strpos($replace, '$0')!==FALSE)
$t = str_replace('$0', $t, $replace);
else
$t = $replace;
}
/**
* Call back replacement of All text
* @param mixed $match
* @param mixed $replace
* @param string $t
* @param int $count
*/
protected static function replace_all_cb(&$match,&$replace,&$t,&$count){
$t = $replace($t);
}
/**
* Static string replacement
*
* @param mixed $match
* @param mixed $replace
* @param string $t
* @param int $count
*/
protected static function replace_str(&$match,&$replace,&$t,&$count){
if (!is_string($match) OR strpos($t,$match)!==FALSE)
$t = str_replace($match, $replace, $t, $count);
}
/**
* Fast Static string replacement one char to one char
*
* @param mixed $match
* @param mixed $replace
* @param string $t
* @param int $count
*/
protected static function replace_strtr(&$match,&$replace,&$t,&$count){
$t = strtr( $t, $match, $replace);
}
/**
* Callback string replacement
*
* @param mixed $match
* @param mixed $replace
* @param string $t
* @param int $count
*/
protected static function replace_str_cb(&$match,&$replace,&$t,&$count){
if (strpos($t,$match)!==FALSE)
if (count($b = explode($match, $t)) > 1)
$t = join($replace($match), $b);
}
/**
* Static Preg replacement
*
* @param mixed $match
* @param mixed $replace
* @param string $t
* @param int $count
*/
protected static function replace_preg(&$match,&$replace,&$t,&$count){
$t = preg_replace($match, $replace, $t, -1, $count);
}
/**
* Callback Preg replacement
* @param mixed $match
* @param mixed $replace
* @param string $t
* @param int $count
*/
protected static function replace_preg_cb(&$match,&$replace,&$t,&$count){
$t = preg_replace_callback($match, $replace, $t, -1, $count);
}
/**
* Static split replacement : invalid
* @param mixed $match
* @param mixed $replace
* @param string $t
* @param int $count
*/
protected static function replace_split(&$match,&$replace,&$t,&$count){
throw new InvalidArgumentException('split rule always needs a callback function as replace');
}
/**
* Callback split replacement
* @param array $match
* @param mixed $replace
* @param string $t
* @param int $count
*/
protected static function replace_split_cb(&$match,&$replace,&$t,&$count){
$a = explode($match[0], $t);
$t = join($match[1], array_map($replace,$a));
}
}
class TextWheelDebug extends TextWheel {
static protected $t; #tableaux des temps
static protected $tu; #tableaux des temps (rules utilises)
static protected $tnu; #tableaux des temps (rules non utilises)
static protected $u; #compteur des rules utiles
static protected $w; #compteur des rules appliques
static $total;
/**
* Timer for profiling
*
* @staticvar int $time
* @param string $t
* @param bool $raw
* @return int/strinf
*/
protected function timer($t='rien', $raw = false) {
static $time;
$a=time(); $b=microtime();
// microtime peut contenir les microsecondes et le temps
$b=explode(' ',$b);
if (count($b)==2) $a = end($b); // plus precis !
$b = reset($b);
if (!isset($time[$t])) {
$time[$t] = $a + $b;
} else {
$p = ($a + $b - $time[$t]) * 1000;
unset($time[$t]);
if ($raw) return $p;
if ($p < 1000)
$s = '';
else {
$s = sprintf("%d ", $x = floor($p/1000));
$p -= ($x*1000);
}
return $s . sprintf("%.3f ms", $p);
}
}
/**
* Apply all rules of RuleSet to a text
*
* @param string $t
* @return string
*/
public function text($t) {
$rules = & $this->ruleset->getRules();
## apply each in order
foreach ($rules as $name => $rule) #php4+php5
{
if (is_int($name))
$name .= ' '.$rule->match;
$this->timer($name);
$b = $t;
$this->apply($rule, $t);
TextWheelDebug::$w[$name] ++; # nombre de fois appliquee
$v = $this->timer($name, true); # timer
TextWheelDebug::$t[$name] += $v;
if ($t !== $b) {
TextWheelDebug::$u[$name] ++; # nombre de fois utile
TextWheelDebug::$tu[$name] += $v;
} else {
TextWheelDebug::$tnu[$name] += $v;
}
}
#foreach ($this->rules as &$rule) #smarter &reference, but php5 only
# $this->apply($rule, $t);
return $t;
}
/**
* Ouputs data stored for profiling/debuging purposes
*/
public static function outputDebug(){
if (isset(TextWheelDebug::$t)) {
$time = array_flip(array_map('strval', TextWheelDebug::$t));
krsort($time);
echo "
<div class='textwheeldebug'>
<style type='text/css'>
.textwheeldebug table { margin:1em 0; }
.textwheeldebug th,.textwheeldebug td { padding-left: 15px }
.textwheeldebug .prof-0 .number { padding-right: 60px }
.textwheeldebug .prof-1 .number { padding-right: 30px }
.textwheeldebug .prof-1 .name { padding-left: 30px }
.textwheeldebug .prof-2 .name { padding-left: 60px }
.textwheeldebug .zero { color:orange; }
.textwheeldebug .number { text-align:right; }
.textwheeldebug .strong { font-weight:bold; }
</style>
<table class='sortable'>
<caption>Temps par rule</caption>
<thead><tr><th>temps (ms)</th><th>rule</th><th>application</th><th>t/u (ms)</th><th>t/n-u (ms)</th></tr></thead>\n";
$total = 0;
foreach($time as $t => $r) {
$applications = intval(TextWheelDebug::$u[$r]);
$total += $t;
if(intval($t*10))
echo "<tr>
<td class='number strong'>".number_format(round($t*10)/10,1)."</td><td> ".spip_htmlspecialchars($r)."</td>
<td"
. (!$applications ? " class='zero'" : "")
.">".$applications."/".intval(TextWheelDebug::$w[$r])."</td>
<td class='number'>".($applications?number_format(round(TextWheelDebug::$tu[$r]/$applications*100)/100,2):"") ."</td>
<td class='number'>".(($nu = intval(TextWheelDebug::$w[$r])-$applications)?number_format(round(TextWheelDebug::$tnu[$r]/$nu*100)/100,2):"") ."</td>
</tr>";
}
echo "</table>\n";
echo "
<table>
<caption>Temps total par rule</caption>
<thead><tr><th>temps</th><th>rule</th></tr></thead>\n";
ksort($GLOBALS['totaux']);
TextWheelDebug::outputTotal($GLOBALS['totaux']);
echo "</table>";
# somme des temps des rules, ne tient pas compte des subwheels
echo "<p>temps total rules: ".round($total)." ms</p>\n";
echo "</div>\n";
}
}
public static function outputTotal($liste, $profondeur=0) {
ksort($liste);
foreach ($liste as $cause => $duree) {
if (is_array($duree)) {
TextWheelDebug::outputTotal($duree, $profondeur+1);
} else {
echo "<tr class='prof-$profondeur'>
<td class='number'><b>".intval($duree)."</b> ms</td>
<td class='name'>".spip_htmlspecialchars($cause)."</td>
</tr>\n";
}
}
}
/**
* Create SubWheel (can be overriden in debug class)
* @param TextWheelRuleset $rules
* @return TextWheel
*/
protected function &createSubWheel(&$rules){
return new TextWheelDebug($rules);
}
}
/**
* stripos for php4
*/
if (!function_exists('stripos')) {
function stripos($haystack, $needle) {
return strpos($haystack, stristr( $haystack, $needle ));
}
}
/**
* approximation of strpbrk for php4
* return false if no char of $char_list is in $haystack
*/
if (!function_exists('strpbrk')) {
function strpbrk($haystack, $char_list) {
$result = strcspn($haystack, $char_list);
if ($result != strlen($haystack)) {
return $result;
}
return false;
}
}
textwheelrule.php 0000666 00000005154 15252560553 0010177 0 ustar 00 <?php
/*
* TextWheel 0.1
*
* let's reinvent the wheel one last time
*
* This library of code is meant to be a fast and universal replacement
* for any and all text-processing systems written in PHP
*
* It is dual-licensed for any use under the GNU/GPL2 and MIT licenses,
* as suits you best
*
* (c) 2009 Fil - fil@rezo.net
* Documentation & http://zzz.rezo.net/-TextWheel-
*
* Usage: $wheel = new TextWheel(); echo $wheel->text($text);
*
*/
if (!defined('_ECRIRE_INC_VERSION')) return;
class TextWheelRule {
## rule description
# optional
var $priority = 0; # rule priority (rules are applied in ascending order)
# -100 = application escape, +100 = application unescape
var $name; # rule's name
var $author; # rule's author
var $url; # rule's homepage
var $package; # rule belongs to package
var $version; # rule version
var $test; # rule test function
var $disabled=false; # true if rule is disabled
## rule init checks
## the rule will be applied if the text...
# optional
var $if_chars; # ...contains one of these chars
var $if_str; # ...contains this string (case sensitive)
var $if_stri; # ...contains this string (case insensitive)
var $if_match; # ...matches this simple expr
## rule effectors, matching
# mandatory
var $type; # 'preg' (default), 'str', 'all', 'split'...
var $match; # matching string or expression
# optional
# var $limit; # limit number of applications (unused)
## rule effectors, replacing
# mandatory
var $replace; # replace match with this expression
# optional
var $is_callback=false; # $replace is a callback function
var $is_wheel; # flag to create a sub-wheel from rules given as replace
var $pick_match = 0; # item to pick for sub-wheel replace
var $glue = null; # glue for implode ending split rule
# optional
# language specific
var $require; # file to require_once
var $create_replace; # do create_function('$m', %) on $this->replace, $m is the matched array
# optimizations
var $func_replace;
/**
* Rule constructor
* @param <type> $args
* @return <type>
*/
public function TextWheelRule($args) {
if (!is_array($args))
return;
foreach($args as $k=>$v)
if (property_exists($this, $k))
$this->$k = $args[$k];
$this->checkValidity(); // check that the rule is valid
}
/**
* Rule checker
*/
protected function checkValidity(){
if ($this->type=='split'){
if (is_array($this->match))
throw new InvalidArgumentException('match argument for split rule can\'t be an array');
if (isset($this->glue) AND is_array($this->glue))
throw new InvalidArgumentException('glue argument for split rule can\'t be an array');
}
}
}