1
+ − 1
<?php
536
+ − 2
+ − 3
/*
+ − 4
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
1081
745200a9cc2a
Fixed some upgrade bugs; added support for choosing one's own date/time formats; rebrand as 1.1.7
Dan
diff
changeset
+ − 5
* Copyright (C) 2006-2009 Dan Fuhry
536
+ − 6
*
+ − 7
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ − 8
* as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ − 9
*
+ − 10
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ − 11
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ − 12
*/
+ − 13
1
+ − 14
/**
1027
+ − 15
* Framework for parsing and rendering various formats. In Enano by default, this is MediaWiki-style wikitext being
+ − 16
* rendered to XHTML, but this framework allows other formats to be supported as well.
1
+ − 17
*
1027
+ − 18
* @package Enano
+ − 19
* @subpackage Content
+ − 20
* @author Dan Fuhry <dan@enanocms.org>
+ − 21
* @copyright (C) 2009 Enano CMS Project
+ − 22
* @license GNU General Public License, version 2 or later <http://www.gnu.org/licenses/gpl-2.0.html>
1
+ − 23
*/
+ − 24
1027
+ − 25
class Carpenter
+ − 26
{
+ − 27
/**
+ − 28
* Parser token
+ − 29
* @const string
+ − 30
*/
+ − 31
+ − 32
const PARSER_TOKEN = "\xFF";
+ − 33
+ − 34
/**
+ − 35
* Parsing engine
+ − 36
* @var string
+ − 37
*/
+ − 38
+ − 39
private $parser = 'mediawiki';
+ − 40
+ − 41
/**
+ − 42
* Rendering engine
+ − 43
* @var string
+ − 44
*/
+ − 45
+ − 46
private $renderer = 'xhtml';
+ − 47
+ − 48
/**
+ − 49
* Rendering flags
+ − 50
*/
+ − 51
+ − 52
public $flags = RENDER_WIKI_DEFAULT;
+ − 53
+ − 54
/**
+ − 55
* List of rendering rules
+ − 56
* @var array
+ − 57
*/
+ − 58
+ − 59
private $rules = array(
+ − 60
'lang',
+ − 61
'templates',
1078
67a4c839c7e1
Blockquote functionality in wikitext parser now allows rendering of other block level elements properly
Dan
diff
changeset
+ − 62
'blockquote',
1027
+ − 63
'tables',
+ − 64
'heading',
1106
+ − 65
'hr',
1027
+ − 66
// note: can't be named list ("list" is a PHP language construct)
+ − 67
'multilist',
+ − 68
'bold',
+ − 69
'italic',
+ − 70
'underline',
+ − 71
'externalwithtext',
+ − 72
'externalnotext',
+ − 73
'image',
+ − 74
'internallink',
1078
67a4c839c7e1
Blockquote functionality in wikitext parser now allows rendering of other block level elements properly
Dan
diff
changeset
+ − 75
'paragraph',
67a4c839c7e1
Blockquote functionality in wikitext parser now allows rendering of other block level elements properly
Dan
diff
changeset
+ − 76
'blockquotepost'
1
+ − 77
);
1027
+ − 78
+ − 79
/**
+ − 80
* List of render hooks
+ − 81
* @var array
+ − 82
*/
+ − 83
+ − 84
private $hooks = array();
+ − 85
+ − 86
/* private $rules = array('prefilter', 'delimiter', 'code', 'function', 'html', 'raw', 'include', 'embed', 'anchor',
+ − 87
'heading', 'toc', 'horiz', 'break', 'blockquote', 'list', 'deflist', 'table', 'image',
+ − 88
'phplookup', 'center', 'newline', 'paragraph', 'url', 'freelink', 'interwiki',
+ − 89
'wikilink', 'colortext', 'strong', 'bold', 'emphasis', 'italic', 'underline', 'tt',
+ − 90
'superscript', 'subscript', 'revise', 'tighten'); */
+ − 91
+ − 92
/**
+ − 93
* Render the text!
+ − 94
* @param string Text to render
+ − 95
* @return string
+ − 96
*/
+ − 97
+ − 98
public function render($text)
+ − 99
{
+ − 100
$parser_class = "Carpenter_Parse_" . ucwords($this->parser);
+ − 101
$renderer_class = "Carpenter_Render_" . ucwords($this->renderer);
+ − 102
1093
+ − 103
// empty?
+ − 104
if ( trim($text) === '' )
+ − 105
return $text;
+ − 106
1027
+ − 107
// include files, if we haven't already
+ − 108
if ( !class_exists($parser_class) )
+ − 109
{
+ − 110
require_once( ENANO_ROOT . "/includes/wikiengine/parse_{$this->parser}.php");
+ − 111
}
+ − 112
+ − 113
if ( !class_exists($renderer_class) )
1
+ − 114
{
1027
+ − 115
require_once( ENANO_ROOT . "/includes/wikiengine/render_{$this->renderer}.php");
+ − 116
}
+ − 117
+ − 118
$parser = new $parser_class;
+ − 119
$renderer = new $renderer_class;
+ − 120
+ − 121
// run prehooks
+ − 122
foreach ( $this->hooks as $hook )
+ − 123
{
+ − 124
if ( $hook['when'] === PO_FIRST )
+ − 125
{
+ − 126
$text = call_user_func($hook['callback'], $text);
+ − 127
if ( !is_string($text) || empty($text) )
+ − 128
{
+ − 129
trigger_error("Hook returned empty/invalid text: " . print_r($hook['callback'], true), E_USER_WARNING);
+ − 130
// *sigh*
+ − 131
$text = '';
1
+ − 132
}
1027
+ − 133
}
+ − 134
}
+ − 135
+ − 136
// perform render
+ − 137
foreach ( $this->rules as $rule )
+ − 138
{
+ − 139
// run prehooks
+ − 140
foreach ( $this->hooks as $hook )
+ − 141
{
+ − 142
if ( $hook['when'] === PO_BEFORE && $hook['rule'] === $rule )
407
+ − 143
{
1027
+ − 144
$text = call_user_func($hook['callback'], $text);
+ − 145
if ( !is_string($text) || empty($text) )
438
+ − 146
{
1027
+ − 147
trigger_error("Hook returned empty/invalid text: " . print_r($hook['callback'], true), E_USER_WARNING);
+ − 148
// *sigh*
+ − 149
$text = '';
438
+ − 150
}
407
+ − 151
}
1
+ − 152
}
1027
+ − 153
+ − 154
// execute rule
+ − 155
$text = $this->perform_render_step($text, $rule, $parser, $renderer);
+ − 156
+ − 157
// run posthooks
+ − 158
foreach ( $this->hooks as $hook )
+ − 159
{
+ − 160
if ( $hook['when'] === PO_AFTER && $hook['rule'] === $rule )
+ − 161
{
+ − 162
$text = call_user_func($hook['callback'], $text);
+ − 163
if ( !is_string($text) || empty($text) )
+ − 164
{
+ − 165
trigger_error("Hook returned empty/invalid text: " . print_r($hook['callback'], true), E_USER_WARNING);
+ − 166
// *sigh*
+ − 167
$text = '';
1
+ − 168
}
+ − 169
}
+ − 170
}
+ − 171
}
1027
+ − 172
+ − 173
// run posthooks
+ − 174
foreach ( $this->hooks as $hook )
1
+ − 175
{
1027
+ − 176
if ( $hook['when'] === PO_LAST )
+ − 177
{
+ − 178
$text = call_user_func($hook['callback'], $text);
+ − 179
if ( !is_string($text) || empty($text) )
+ − 180
{
+ − 181
trigger_error("Hook returned empty/invalid text: " . print_r($hook['callback'], true), E_USER_WARNING);
+ − 182
// *sigh*
+ − 183
$text = '';
1
+ − 184
}
+ − 185
}
+ − 186
}
1027
+ − 187
+ − 188
return (( defined('ENANO_DEBUG') && isset($_GET['parserdebug']) ) ? '<pre>' . htmlspecialchars($text) . '</pre>' : $text) . "\n\n";
+ − 189
}
+ − 190
+ − 191
/**
+ − 192
* Performs a step in the rendering process.
+ − 193
* @param string Text to render
+ − 194
* @param string Rule to execute
+ − 195
* @param object Parser instance
+ − 196
* @param object Renderer instance
+ − 197
* @return string
+ − 198
* @access private
+ − 199
*/
+ − 200
+ − 201
private function perform_render_step($text, $rule, $parser, $renderer)
+ − 202
{
+ − 203
// First look for a direct function
+ − 204
if ( function_exists("parser_{$this->parser}_{$this->renderer}_{$rule}") )
1
+ − 205
{
1027
+ − 206
return call_user_func("parser_{$this->parser}_{$this->renderer}_{$rule}", $text, $this->flags);
1
+ − 207
}
1027
+ − 208
+ − 209
// We don't have that, so start looking for other ways or means of doing this
+ − 210
if ( method_exists($parser, $rule) && method_exists($renderer, $rule) )
+ − 211
{
+ − 212
// Both the parser and render have callbacks they want to use.
+ − 213
$pieces = $parser->$rule($text);
+ − 214
$text = call_user_func(array($renderer, $rule), $text, $pieces);
+ − 215
}
+ − 216
else if ( method_exists($parser, $rule) && !method_exists($renderer, $rule) && isset($renderer->rules[$rule]) )
1
+ − 217
{
1027
+ − 218
// The parser has a callback, but the renderer does not
+ − 219
$pieces = $parser->$rule($text);
+ − 220
$text = $this->generic_render($text, $pieces, $renderer->rules[$rule]);
1
+ − 221
}
1027
+ − 222
else if ( !method_exists($parser, $rule) && isset($parser->rules[$rule]) && method_exists($renderer, $rule) )
1
+ − 223
{
1027
+ − 224
// The parser has no callback, but the renderer does
+ − 225
$text = preg_replace_callback($parser->rules[$rule], array($renderer, $rule), $text);
+ − 226
}
+ − 227
else if ( isset($parser->rules[$rule]) && isset($renderer->rules[$rule]) )
+ − 228
{
+ − 229
// This is a straight-up regex only rule
+ − 230
$text = preg_replace($parser->rules[$rule], $renderer->rules[$rule], $text);
+ − 231
}
+ − 232
else
+ − 233
{
+ − 234
// Either the renderer or parser does not support this rule, ignore it
1
+ − 235
}
1027
+ − 236
+ − 237
return $text;
+ − 238
}
+ − 239
+ − 240
/**
+ − 241
* Generic renderer
+ − 242
* @access protected
+ − 243
*/
+ − 244
+ − 245
protected function generic_render($text, $pieces, $rule)
+ − 246
{
+ − 247
foreach ( $pieces as $i => $piece )
1
+ − 248
{
1027
+ − 249
$replacement = $rule;
+ − 250
+ − 251
// if the piece is an array, replace $1, $2, etc. in the rule with each value in the piece
+ − 252
if ( is_array($piece) )
+ − 253
{
+ − 254
$j = 0;
+ − 255
foreach ( $piece as $part )
+ − 256
{
+ − 257
$j++;
+ − 258
$replacement = str_replace(array("\\$j", "\${$j}"), $part, $replacement);
1
+ − 259
}
1027
+ − 260
}
+ − 261
// else, just replace \\1 or $1 in the rule with the piece
+ − 262
else
+ − 263
{
+ − 264
$replacement = str_replace(array("\\1", "\$1"), $piece, $replacement);
+ − 265
}
+ − 266
+ − 267
$text = str_replace(self::generate_token($i), $replacement, $text);
1
+ − 268
}
1027
+ − 269
+ − 270
return $text;
+ − 271
}
+ − 272
+ − 273
/**
+ − 274
* Add a hook into the parser.
+ − 275
* @param callback Function to call
+ − 276
* @param int PO_* constant
+ − 277
* @param string If PO_{BEFORE,AFTER} used, rule
+ − 278
*/
+ − 279
+ − 280
public function hook($callback, $when, $rule = false)
+ − 281
{
+ − 282
if ( !is_int($when) )
+ − 283
return null;
+ − 284
if ( ($when == PO_BEFORE || $when == PO_AFTER) && !is_string($rule) )
+ − 285
return null;
+ − 286
if ( ( is_string($callback) && !function_exists($callback) ) || ( is_array($callback) && !method_exists($callback[0], $callback[1]) ) || ( !is_string($callback) && !is_array($callback) ) )
1
+ − 287
{
1027
+ − 288
trigger_error("Attempt to hook with undefined function/method " . print_r($callback, true), E_USER_ERROR);
+ − 289
return null;
1
+ − 290
}
1027
+ − 291
+ − 292
$this->hooks[] = array(
+ − 293
'callback' => $callback,
+ − 294
'when' => $when,
+ − 295
'rule' => $rule
+ − 296
);
+ − 297
}
+ − 298
+ − 299
/**
1031
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 300
* Disable a render stage
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 301
* @param string stage
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 302
* @return null
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 303
*/
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 304
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 305
public function disable_rule($rule)
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 306
{
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 307
foreach ( $this->rules as $i => $current_rule )
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 308
{
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 309
if ( $current_rule === $rule )
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 310
{
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 311
unset($this->rules[$i]);
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 312
return null;
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 313
}
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 314
}
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 315
return null;
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 316
}
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 317
8a4b75e73137
Wiki formatting: Headings: tolerate spaces after line; added disable_rule method (required for rev. 1029)
Dan
diff
changeset
+ − 318
/**
1108
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 319
* Disables all rules.
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 320
* @return null
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 321
*/
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 322
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 323
public function disable_all_rules()
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 324
{
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 325
$this->rules = array();
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 326
return null;
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 327
}
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 328
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 329
/**
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 330
* Enables a rule
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 331
* @param string rule
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 332
* @return null
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 333
*/
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 334
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 335
public function enable_rule($rule)
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 336
{
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 337
$this->rules[] = $rule;
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 338
return null;
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 339
}
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 340
c1be67a50d81
Removed the $userpage parameter from Namespace_Default::error_404(). It screwed up a couple plugins. (Thanks Mazza for discovering the issue)
Dan
diff
changeset
+ − 341
/**
1054
e6b14d33ac55
Renderer: added "smart paragraphs" for templates. <p><b>Foo</b> {bar}</p> where bar is multiline is basically turned into proper XHTML paragraphs.
Dan
diff
changeset
+ − 342
* Make a rule exclusive (the only one called)
e6b14d33ac55
Renderer: added "smart paragraphs" for templates. <p><b>Foo</b> {bar}</p> where bar is multiline is basically turned into proper XHTML paragraphs.
Dan
diff
changeset
+ − 343
* @param string stage
e6b14d33ac55
Renderer: added "smart paragraphs" for templates. <p><b>Foo</b> {bar}</p> where bar is multiline is basically turned into proper XHTML paragraphs.
Dan
diff
changeset
+ − 344
* @return null
e6b14d33ac55
Renderer: added "smart paragraphs" for templates. <p><b>Foo</b> {bar}</p> where bar is multiline is basically turned into proper XHTML paragraphs.
Dan
diff
changeset
+ − 345
*/
e6b14d33ac55
Renderer: added "smart paragraphs" for templates. <p><b>Foo</b> {bar}</p> where bar is multiline is basically turned into proper XHTML paragraphs.
Dan
diff
changeset
+ − 346
e6b14d33ac55
Renderer: added "smart paragraphs" for templates. <p><b>Foo</b> {bar}</p> where bar is multiline is basically turned into proper XHTML paragraphs.
Dan
diff
changeset
+ − 347
public function exclusive_rule($rule)
e6b14d33ac55
Renderer: added "smart paragraphs" for templates. <p><b>Foo</b> {bar}</p> where bar is multiline is basically turned into proper XHTML paragraphs.
Dan
diff
changeset
+ − 348
{
e6b14d33ac55
Renderer: added "smart paragraphs" for templates. <p><b>Foo</b> {bar}</p> where bar is multiline is basically turned into proper XHTML paragraphs.
Dan
diff
changeset
+ − 349
if ( is_string($rule) )
e6b14d33ac55
Renderer: added "smart paragraphs" for templates. <p><b>Foo</b> {bar}</p> where bar is multiline is basically turned into proper XHTML paragraphs.
Dan
diff
changeset
+ − 350
$this->rules = array($rule);
e6b14d33ac55
Renderer: added "smart paragraphs" for templates. <p><b>Foo</b> {bar}</p> where bar is multiline is basically turned into proper XHTML paragraphs.
Dan
diff
changeset
+ − 351
e6b14d33ac55
Renderer: added "smart paragraphs" for templates. <p><b>Foo</b> {bar}</p> where bar is multiline is basically turned into proper XHTML paragraphs.
Dan
diff
changeset
+ − 352
return null;
e6b14d33ac55
Renderer: added "smart paragraphs" for templates. <p><b>Foo</b> {bar}</p> where bar is multiline is basically turned into proper XHTML paragraphs.
Dan
diff
changeset
+ − 353
}
e6b14d33ac55
Renderer: added "smart paragraphs" for templates. <p><b>Foo</b> {bar}</p> where bar is multiline is basically turned into proper XHTML paragraphs.
Dan
diff
changeset
+ − 354
e6b14d33ac55
Renderer: added "smart paragraphs" for templates. <p><b>Foo</b> {bar}</p> where bar is multiline is basically turned into proper XHTML paragraphs.
Dan
diff
changeset
+ − 355
/**
1027
+ − 356
* Generate a token
+ − 357
* @param int Token index
+ − 358
* @return string
+ − 359
* @static
+ − 360
*/
+ − 361
+ − 362
public static function generate_token($i)
+ − 363
{
+ − 364
return self::PARSER_TOKEN . $i . self::PARSER_TOKEN;
+ − 365
}
+ − 366
+ − 367
/**
+ − 368
* Tokenize string
+ − 369
* @param string
+ − 370
* @param array Matches
+ − 371
* @return string
+ − 372
* @static
+ − 373
*/
+ − 374
+ − 375
public static function tokenize($text, $matches)
+ − 376
{
+ − 377
$matches = array_values($matches);
+ − 378
foreach ( $matches as $i => $match )
1
+ − 379
{
1027
+ − 380
$text = str_replace_once($match, self::generate_token($i), $text);
1
+ − 381
}
1027
+ − 382
+ − 383
return $text;
+ − 384
}
1
+ − 385
}
+ − 386