textwheelruleset.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <?php
  2. /*
  3. * TextWheel 0.1
  4. *
  5. * let's reinvent the wheel one last time
  6. *
  7. * This library of code is meant to be a fast and universal replacement
  8. * for any and all text-processing systems written in PHP
  9. *
  10. * It is dual-licensed for any use under the GNU/GPL2 and MIT licenses,
  11. * as suits you best
  12. *
  13. * (c) 2009 Fil - fil@rezo.net
  14. * Documentation & http://zzz.rezo.net/-TextWheel-
  15. *
  16. * Usage: $wheel = new TextWheel(); echo $wheel->text($text);
  17. *
  18. */
  19. if (!defined('_ECRIRE_INC_VERSION')) return;
  20. require_once dirname(__FILE__)."/textwheelrule.php";
  21. abstract class TextWheelDataSet {
  22. # list of data
  23. protected $data = array();
  24. /**
  25. * file finder : can be overloaded in order to use application dependant
  26. * path find method
  27. *
  28. * @param string $file
  29. * @param string $path
  30. * @return string
  31. */
  32. protected function findFile(&$file, $path=''){
  33. static $default_path;
  34. // absolute file path ?
  35. if (file_exists($file))
  36. return $file;
  37. // file embed with texwheels, relative to calling ruleset
  38. if ($path AND file_exists($f = $path.$file))
  39. return $f;
  40. // textwheel default path ?
  41. if (!$default_path)
  42. $default_path = dirname(__FILE__).'/../wheels/';
  43. if (file_exists($f = $default_path.$file))
  44. return $f;
  45. return false;
  46. }
  47. /**
  48. * Load a yaml file describing data
  49. * @param string $file
  50. * @param string $default_path
  51. * @return array
  52. */
  53. protected function loadFile(&$file, $default_path='') {
  54. if (!preg_match(',[.]yaml$,i',$file)
  55. // external rules
  56. OR !$file = $this->findFile($file,$default_path))
  57. return array();
  58. defined('_YAML_EVAL_PHP') || define('_YAML_EVAL_PHP', false);
  59. if (!function_exists('yaml_decode')) {
  60. if (function_exists('include_spip'))
  61. include_spip('inc/yaml-mini');
  62. else
  63. require_once dirname(__FILE__).'/../inc/yaml.php';
  64. }
  65. $dataset = yaml_decode(file_get_contents($file));
  66. if (is_null($dataset))
  67. $dataset = array();
  68. # throw new DomainException('yaml file is empty, unreadable or badly formed: '.$file.var_export($dataset,true));
  69. // if a php file with same name exists
  70. // include it as it contains callback functions
  71. if ($f = preg_replace(',[.]yaml$,i','.php',$file)
  72. AND file_exists($f)) {
  73. $dataset[] = array('require' => $f, 'priority' => -1000);
  74. }
  75. return $dataset;
  76. }
  77. }
  78. class TextWheelRuleSet extends TextWheelDataSet {
  79. # sort flag
  80. protected $sorted = true;
  81. /**
  82. * Constructor
  83. *
  84. * @param array|string $ruleset
  85. * @param string $filepath
  86. */
  87. public function TextWheelRuleSet($ruleset = array(), $filepath='') {
  88. if ($ruleset)
  89. $this->addRules($ruleset, $filepath);
  90. }
  91. /**
  92. * public static loader
  93. * can be overloaded to use memoization
  94. *
  95. * @param array $ruleset
  96. * @param string $callback
  97. * @param string $class
  98. * @return class
  99. */
  100. public static function &loader($ruleset, $callback='', $class='TextWheelRuleSet'){
  101. $ruleset = new $class($ruleset);
  102. if ($callback)
  103. $callback($ruleset);
  104. return $ruleset;
  105. }
  106. /**
  107. * Get an existing named rule in order to override it
  108. *
  109. * @param string $name
  110. * @return string
  111. */
  112. public function &getRule($name){
  113. if (isset($this->data[$name]))
  114. return $this->data[$name];
  115. $result = null;
  116. return $result;
  117. }
  118. /**
  119. * get sorted Rules
  120. * @return array
  121. */
  122. public function &getRules(){
  123. $this->sort();
  124. return $this->data;
  125. }
  126. /**
  127. * add a rule
  128. *
  129. * @param TextWheelRule $rule
  130. */
  131. public function addRule($rule) {
  132. # cast array-rule to object
  133. if (is_array($rule))
  134. $rule = new TextWheelRule($rule);
  135. $this->data[] = $rule;
  136. $this->sorted = false;
  137. }
  138. /**
  139. * add an list of rules
  140. * can be
  141. * - an array of rules
  142. * - a string filename
  143. * - an array of string filename
  144. *
  145. * @param array|string $rules
  146. * @param string $filepath
  147. */
  148. public function addRules($rules, $filepath='') {
  149. // rules can be an array of filename
  150. if (is_array($rules) AND is_string(reset($rules))) {
  151. foreach($rules as $i=>$filename)
  152. $this->addRules($filename);
  153. return;
  154. }
  155. // rules can be a string : yaml filename
  156. if (is_string($rules)) {
  157. $file = $rules; // keep the real filename
  158. $rules = $this->loadFile($file, $filepath);
  159. $filepath = dirname($file).'/';
  160. }
  161. // rules can be an array of rules
  162. if (is_array($rules) AND count($rules)){
  163. # cast array-rules to objects
  164. foreach ($rules as $i => $rule) {
  165. if (is_array($rule))
  166. $rules[$i] = new TextWheelRule($rule);
  167. // load subwheels when necessary
  168. if ($rules[$i]->is_wheel){
  169. // subruleset is of the same class as current ruleset
  170. $class = get_class($this);
  171. $rules[$i]->replace = new $class($rules[$i]->replace, $filepath);
  172. }
  173. }
  174. $this->data = array_merge($this->data, $rules);
  175. $this->sorted = false;
  176. }
  177. }
  178. /**
  179. * Sort rules according to priority and
  180. * purge disabled rules
  181. *
  182. */
  183. protected function sort() {
  184. if (!$this->sorted) {
  185. $rulz = array();
  186. foreach($this->data as $index => $rule)
  187. if (!$rule->disabled)
  188. $rulz[intval($rule->priority)][$index] = $rule;
  189. ksort($rulz);
  190. $this->data = array();
  191. foreach($rulz as $rules)
  192. $this->data += $rules;
  193. $this->sorted = true;
  194. }
  195. }
  196. }