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