1<?php 2// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: 3/** 4 * Baseline rule class for extension into a "real" parser component. 5 * 6 * PHP versions 4 and 5 7 * 8 * @category Text 9 * @package Text_Wiki 10 * @author Paul M. Jones <pmjones@php.net> 11 * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 12 * @version CVS: $Id$ 13 * @link http://pear.php.net/package/Text_Wiki 14 */ 15 16/** 17 * Baseline rule class for extension into a "real" parser component. 18 * 19 * Text_Wiki_Rule classes do not stand on their own; they are called by a 20 * Text_Wiki object, typcially in the transform() method. Each rule class 21 * performs three main activities: parse, process, and render. 22 * 23 * The parse() method takes a regex and applies it to the whole block of 24 * source text at one time. Each match is sent as $matches to the 25 * process() method. 26 * 27 * The process() method acts on the matched text from the source, and 28 * then processes the source text is some way. This may mean the 29 * creation of a delimited token using addToken(). In every case, the 30 * process() method returns the text that should replace the matched text 31 * from parse(). 32 * 33 * @category Text 34 * @package Text_Wiki 35 * @author Paul M. Jones <pmjones@php.net> 36 * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 37 * @version Release: @package_version@ 38 * @link http://pear.php.net/package/Text_Wiki 39 */ 40class Text_Wiki_Parse { 41 42 43 /** 44 * 45 * Configuration options for this parser rule. 46 * 47 * @access public 48 * 49 * @var string 50 * 51 */ 52 53 var $conf = array(); 54 55 56 /** 57 * 58 * Regular expression to find matching text for this rule. 59 * 60 * @access public 61 * 62 * @var string 63 * 64 * @see parse() 65 * 66 */ 67 68 var $regex = null; 69 70 71 /** 72 * 73 * The name of this rule for new token array elements. 74 * 75 * @access public 76 * 77 * @var string 78 * 79 */ 80 81 var $rule = null; 82 83 84 /** 85 * 86 * A reference to the calling Text_Wiki object. 87 * 88 * This is needed so that each rule has access to the same source 89 * text, token set, URLs, interwiki maps, page names, etc. 90 * 91 * @access public 92 * 93 * @var object 94 */ 95 96 var $wiki = null; 97 98 99 /** 100 * 101 * Constructor for this parser rule. 102 * 103 * @access public 104 * 105 * @param object &$obj The calling "parent" Text_Wiki object. 106 * 107 */ 108 109 function __construct(&$obj) 110 { 111 // set the reference to the calling Text_Wiki object; 112 // this allows us access to the shared source text, token 113 // array, etc. 114 $this->wiki =& $obj; 115 116 // set the name of this rule; generally used when adding 117 // to the tokens array. strip off the Text_Wiki_Parse_ portion. 118 // text_wiki_parse_ 119 // 0123456789012345 120 $tmp = substr(get_class($this), 16); 121 $this->rule = ucwords(strtolower($tmp)); 122 123 // override config options for the rule if specified 124 if (isset($this->wiki->parseConf[$this->rule]) && 125 is_array($this->wiki->parseConf[$this->rule])) { 126 127 $this->conf = array_merge( 128 $this->conf, 129 $this->wiki->parseConf[$this->rule] 130 ); 131 132 } 133 } 134 135 136 /** 137 * 138 * Abstrct method to parse source text for matches. 139 * 140 * Applies the rule's regular expression to the source text, passes 141 * every match to the process() method, and replaces the matched text 142 * with the results of the processing. 143 * 144 * @access public 145 * 146 * @see Text_Wiki_Parse::process() 147 * 148 */ 149 150 function parse() 151 { 152 $this->wiki->source = preg_replace_callback( 153 $this->regex, 154 array(&$this, 'process'), 155 $this->wiki->source 156 ); 157 } 158 159 160 /** 161 * 162 * Abstract method to generate replacements for matched text. 163 * 164 * @access public 165 * 166 * @param array $matches An array of matches from the parse() method 167 * as generated by preg_replace_callback. $matches[0] is the full 168 * matched string, $matches[1] is the first matched pattern, 169 * $matches[2] is the second matched pattern, and so on. 170 * 171 * @return string The processed text replacement; defaults to the 172 * full matched string (i.e., no changes to the text). 173 * 174 * @see Text_Wiki_Parse::parse() 175 * 176 */ 177 178 function process(&$matches) 179 { 180 return $matches[0]; 181 } 182 183 184 /** 185 * 186 * Simple method to safely get configuration key values. 187 * 188 * @access public 189 * 190 * @param string $key The configuration key. 191 * 192 * @param mixed $default If the key does not exist, return this value 193 * instead. 194 * 195 * @return mixed The configuration key value (if it exists) or the 196 * default value (if not). 197 * 198 */ 199 200 function getConf($key, $default = null) 201 { 202 if (isset($this->conf[$key])) { 203 return $this->conf[$key]; 204 } else { 205 return $default; 206 } 207 } 208 209 210 /** 211 * 212 * Extract 'attribute="value"' portions of wiki markup. 213 * 214 * This kind of markup is typically used only in macros, but is useful 215 * anywhere. 216 * 217 * The syntax is pretty strict; there can be no spaces between the 218 * option name, the equals, and the first double-quote; the value 219 * must be surrounded by double-quotes. You can escape characters in 220 * the value with a backslash, and the backslash will be stripped for 221 * you. 222 * 223 * @access public 224 * 225 * @param string $text The "attributes" portion of markup. 226 * 227 * @return array An associative array of key-value pairs where the 228 * key is the option name and the value is the option value. 229 * 230 */ 231 232 function getAttrs($text) 233 { 234 // find the =" sections; 235 $tmp = explode('="', trim($text)); 236 237 // basic setup 238 $k = count($tmp) - 1; 239 $attrs = array(); 240 $key = null; 241 242 // loop through the sections 243 foreach ($tmp as $i => $val) { 244 245 // first element is always the first key 246 if ($i == 0) { 247 $key = trim($val); 248 continue; 249 } 250 251 // find the last double-quote in the value. 252 // the part to the left is the value for the last key, 253 // the part to the right is the next key name 254 $pos = strrpos($val, '"'); 255 $attrs[$key] = stripslashes(substr($val, 0, $pos)); 256 $key = trim(substr($val, $pos+1)); 257 258 } 259 260 return $attrs; 261 262 } 263} 264?> 265