1
+ − 1
<?php
+ − 2
/**
+ − 3
* Parse structured wiki text and render into arbitrary formats such as XHTML.
+ − 4
*
+ − 5
* PHP versions 4 and 5
+ − 6
*
+ − 7
* @category Text
+ − 8
* @package Text_Wiki
+ − 9
* @author Paul M. Jones <pmjones@php.net>
+ − 10
* @license http://www.gnu.org/licenses/lgpl.html
+ − 11
* @version CVS: $Id: Wiki.php,v 1.44 2006/03/02 04:04:59 justinpatrin Exp $
+ − 12
* @link http://wiki.ciaweb.net/yawiki/index.php?area=Text_Wiki
+ − 13
*
+ − 14
* This code was modified for use in Enano. The Text_Wiki engine is licensed
+ − 15
* under the GNU Lesser General Public License; see
+ − 16
* http://www.gnu.org/licenses/lgpl.html for details.
+ − 17
*
+ − 18
*/
+ − 19
+ − 20
require_once ENANO_ROOT.'/includes/wikiengine/Parse.php';
+ − 21
require_once ENANO_ROOT.'/includes/wikiengine/Render.php';
+ − 22
+ − 23
class Text_Wiki {
+ − 24
+ − 25
var $rules = array(
+ − 26
'Prefilter',
+ − 27
'Delimiter',
+ − 28
'Code',
+ − 29
'Function',
+ − 30
'Html',
+ − 31
'Raw',
+ − 32
'Include',
+ − 33
'Embed',
+ − 34
'Anchor',
+ − 35
'Heading',
+ − 36
'Toc',
+ − 37
'Horiz',
+ − 38
'Break',
+ − 39
'Blockquote',
+ − 40
'List',
+ − 41
'Deflist',
+ − 42
'Table',
+ − 43
'Image',
+ − 44
'Phplookup',
+ − 45
'Center',
+ − 46
'Newline',
+ − 47
'Paragraph',
+ − 48
'Url',
+ − 49
'Freelink',
+ − 50
'Interwiki',
+ − 51
'Wikilink',
+ − 52
'Colortext',
+ − 53
'Strong',
+ − 54
'Bold',
+ − 55
'Emphasis',
+ − 56
'Italic',
+ − 57
'Underline',
+ − 58
'Tt',
+ − 59
'Superscript',
+ − 60
'Subscript',
+ − 61
'Revise',
+ − 62
'Tighten'
+ − 63
);
+ − 64
+ − 65
var $disable = array(
+ − 66
'Html',
+ − 67
'Include',
32
4d87aad3c4c0
Finished everything on the TODO list (yay!); several CSS cleanups; tons more changes in this commit - see the patch for details
Dan
diff
changeset
+ − 68
'Embed',
35
+ − 69
'Tighten',
142
ca9118d9c0f2
Rebrand as 1.0.2 (Coblynau); internal links are now parsed by RenderMan::parse_internal_links()
Dan
diff
changeset
+ − 70
'Image',
ca9118d9c0f2
Rebrand as 1.0.2 (Coblynau); internal links are now parsed by RenderMan::parse_internal_links()
Dan
diff
changeset
+ − 71
'Wikilink'
1
+ − 72
);
+ − 73
+ − 74
var $parseConf = array();
+ − 75
+ − 76
var $renderConf = array(
+ − 77
'Docbook' => array(),
+ − 78
'Latex' => array(),
+ − 79
'Pdf' => array(),
+ − 80
'Plain' => array(),
+ − 81
'Rtf' => array(),
+ − 82
'Xhtml' => array()
+ − 83
);
+ − 84
+ − 85
var $formatConf = array(
+ − 86
'Docbook' => array(),
+ − 87
'Latex' => array(),
+ − 88
'Pdf' => array(),
+ − 89
'Plain' => array(),
+ − 90
'Rtf' => array(),
+ − 91
'Xhtml' => array()
+ − 92
);
+ − 93
var $delim = "\xFF";
+ − 94
var $tokens = array();
+ − 95
var $_countRulesTokens = array();
+ − 96
var $source = '';
+ − 97
var $parseObj = array();
+ − 98
var $renderObj = array();
+ − 99
var $formatObj = array();
+ − 100
var $path = array(
+ − 101
'parse' => array(),
+ − 102
'render' => array()
+ − 103
);
+ − 104
var $_dirSep = DIRECTORY_SEPARATOR;
+ − 105
function Text_Wiki($rules = null)
+ − 106
{
+ − 107
if (is_array($rules)) {
+ − 108
$this->rules = $rules;
+ − 109
}
407
+ − 110
+ − 111
global $plugins;
+ − 112
$code = $plugins->setHook('text_wiki_construct');
+ − 113
foreach ( $code as $cmd )
+ − 114
{
+ − 115
eval($cmd);
+ − 116
}
1
+ − 117
+ − 118
$this->addPath(
+ − 119
'parse',
+ − 120
$this->fixPath(ENANO_ROOT) . 'includes/wikiengine/Parse/Default/'
+ − 121
);
+ − 122
$this->addPath(
+ − 123
'render',
+ − 124
$this->fixPath(ENANO_ROOT) . 'includes/wikiengine/Render/'
+ − 125
);
+ − 126
+ − 127
}
+ − 128
371
dc6026376919
Improved compatibility with PostgreSQL and fixed a number of installer bugs; fixed missing "meta" category declaration in language files
Dan
diff
changeset
+ − 129
public static function singleton($parser = 'Default', $rules = null)
1
+ − 130
{
+ − 131
static $only = array();
+ − 132
if (!isset($only[$parser])) {
371
dc6026376919
Improved compatibility with PostgreSQL and fixed a number of installer bugs; fixed missing "meta" category declaration in language files
Dan
diff
changeset
+ − 133
$ret = Text_Wiki::factory($parser, $rules);
1
+ − 134
if (!$ret) {
+ − 135
return $ret;
+ − 136
}
+ − 137
$only[$parser] =& $ret;
+ − 138
}
+ − 139
return $only[$parser];
+ − 140
}
+ − 141
371
dc6026376919
Improved compatibility with PostgreSQL and fixed a number of installer bugs; fixed missing "meta" category declaration in language files
Dan
diff
changeset
+ − 142
public static function factory($parser = 'Default', $rules = null)
1
+ − 143
{
+ − 144
$d=getcwd();
+ − 145
chdir(ENANO_ROOT);
+ − 146
+ − 147
$class = 'Text_Wiki_' . $parser;
+ − 148
$c2 = '._includes_wikiengine_' . $parser;
+ − 149
$file = str_replace('_', '/', $c2).'.php';
+ − 150
if (!class_exists($class)) {
+ − 151
$fp = @fopen($file, 'r', true);
+ − 152
if ($fp === false) {
+ − 153
die_semicritical('Wiki formatting engine error', '<p>Could not find file '.$file.' in include_path</p>');
+ − 154
}
+ − 155
fclose($fp);
+ − 156
include_once($file);
+ − 157
if (!class_exists($class)) {
+ − 158
die_semicritical('Wiki formatting engine error', '<p>Class '.$class.' does not exist after including '.$file.'</p>');
+ − 159
}
+ − 160
}
+ − 161
+ − 162
chdir($d);
+ − 163
345
4ccdfeee9a11
WiP commit for admin panel localization. All modules up to Admin:UserManager (working down the list) are localized except Admin:ThemeManager, which is due for a rewrite
Dan
diff
changeset
+ − 164
$obj = new $class($rules);
1
+ − 165
return $obj;
+ − 166
}
+ − 167
+ − 168
function setParseConf($rule, $arg1, $arg2 = null)
+ − 169
{
+ − 170
$rule = ucwords(strtolower($rule));
+ − 171
+ − 172
if (! isset($this->parseConf[$rule])) {
+ − 173
$this->parseConf[$rule] = array();
+ − 174
}
+ − 175
+ − 176
if (is_array($arg1)) {
+ − 177
$this->parseConf[$rule] = $arg1;
+ − 178
} else {
+ − 179
$this->parseConf[$rule][$arg1] = $arg2;
+ − 180
}
+ − 181
}
+ − 182
+ − 183
function getParseConf($rule, $key = null)
+ − 184
{
+ − 185
$rule = ucwords(strtolower($rule));
+ − 186
+ − 187
if (! isset($this->parseConf[$rule])) {
+ − 188
return null;
+ − 189
}
+ − 190
+ − 191
if (is_null($key)) {
+ − 192
return $this->parseConf[$rule];
+ − 193
}
+ − 194
+ − 195
if (isset($this->parseConf[$rule][$key])) {
+ − 196
return $this->parseConf[$rule][$key];
+ − 197
} else {
+ − 198
return null;
+ − 199
}
+ − 200
}
+ − 201
+ − 202
function setRenderConf($format, $rule, $arg1, $arg2 = null)
+ − 203
{
+ − 204
$format = ucwords(strtolower($format));
+ − 205
$rule = ucwords(strtolower($rule));
+ − 206
+ − 207
if (! isset($this->renderConf[$format])) {
+ − 208
$this->renderConf[$format] = array();
+ − 209
}
+ − 210
+ − 211
if (! isset($this->renderConf[$format][$rule])) {
+ − 212
$this->renderConf[$format][$rule] = array();
+ − 213
}
+ − 214
+ − 215
if (is_array($arg1)) {
+ − 216
$this->renderConf[$format][$rule] = $arg1;
+ − 217
} else {
+ − 218
$this->renderConf[$format][$rule][$arg1] = $arg2;
+ − 219
}
+ − 220
}
+ − 221
+ − 222
function getRenderConf($format, $rule, $key = null)
+ − 223
{
+ − 224
$format = ucwords(strtolower($format));
+ − 225
$rule = ucwords(strtolower($rule));
+ − 226
+ − 227
if (! isset($this->renderConf[$format]) ||
+ − 228
! isset($this->renderConf[$format][$rule])) {
+ − 229
return null;
+ − 230
}
+ − 231
+ − 232
if (is_null($key)) {
+ − 233
return $this->renderConf[$format][$rule];
+ − 234
}
+ − 235
+ − 236
if (isset($this->renderConf[$format][$rule][$key])) {
+ − 237
return $this->renderConf[$format][$rule][$key];
+ − 238
} else {
+ − 239
return null;
+ − 240
}
+ − 241
+ − 242
}
+ − 243
+ − 244
function setFormatConf($format, $arg1, $arg2 = null)
+ − 245
{
+ − 246
if (! is_array($this->formatConf[$format])) {
+ − 247
$this->formatConf[$format] = array();
+ − 248
}
+ − 249
+ − 250
if (is_array($arg1)) {
+ − 251
$this->formatConf[$format] = $arg1;
+ − 252
} else {
+ − 253
$this->formatConf[$format][$arg1] = $arg2;
+ − 254
}
+ − 255
}
+ − 256
+ − 257
function getFormatConf($format, $key = null)
+ − 258
{
+ − 259
if (! isset($this->formatConf[$format])) {
+ − 260
return null;
+ − 261
}
+ − 262
+ − 263
if (is_null($key)) {
+ − 264
return $this->formatConf[$format];
+ − 265
}
+ − 266
+ − 267
if (isset($this->formatConf[$format][$key])) {
+ − 268
return $this->formatConf[$format][$key];
+ − 269
} else {
+ − 270
return null;
+ − 271
}
+ − 272
}
+ − 273
+ − 274
function insertRule($name, $tgt = null)
+ − 275
{
+ − 276
$name = ucwords(strtolower($name));
+ − 277
if (! is_null($tgt)) {
+ − 278
$tgt = ucwords(strtolower($tgt));
+ − 279
}
+ − 280
if (in_array($name, $this->rules)) {
+ − 281
return null;
+ − 282
}
+ − 283
+ − 284
if (! is_null($tgt) && $tgt != '' &&
+ − 285
! in_array($tgt, $this->rules)) {
+ − 286
return false;
+ − 287
}
+ − 288
+ − 289
if (is_null($tgt)) {
+ − 290
$this->rules[] = $name;
+ − 291
return true;
+ − 292
}
+ − 293
+ − 294
if ($tgt == '') {
+ − 295
array_unshift($this->rules, $name);
+ − 296
return true;
+ − 297
}
+ − 298
+ − 299
$tmp = $this->rules;
+ − 300
$this->rules = array();
+ − 301
+ − 302
foreach ($tmp as $val) {
+ − 303
$this->rules[] = $val;
+ − 304
if ($val == $tgt) {
+ − 305
$this->rules[] = $name;
+ − 306
}
+ − 307
}
+ − 308
+ − 309
return true;
+ − 310
}
+ − 311
+ − 312
function deleteRule($name)
+ − 313
{
+ − 314
$name = ucwords(strtolower($name));
+ − 315
$key = array_search($name, $this->rules);
+ − 316
if ($key !== false) {
+ − 317
unset($this->rules[$key]);
+ − 318
}
+ − 319
}
+ − 320
+ − 321
function changeRule($old, $new)
+ − 322
{
+ − 323
$old = ucwords(strtolower($old));
+ − 324
$new = ucwords(strtolower($new));
+ − 325
$key = array_search($old, $this->rules);
+ − 326
if ($key !== false) {
+ − 327
$this->deleteRule($new);
+ − 328
$this->rules[$key] = $new;
+ − 329
}
+ − 330
}
+ − 331
+ − 332
function enableRule($name)
+ − 333
{
+ − 334
$name = ucwords(strtolower($name));
+ − 335
$key = array_search($name, $this->disable);
+ − 336
if ($key !== false) {
+ − 337
unset($this->disable[$key]);
+ − 338
}
+ − 339
}
+ − 340
+ − 341
function disableRule($name)
+ − 342
{
+ − 343
$name = ucwords(strtolower($name));
+ − 344
$key = array_search($name, $this->disable);
+ − 345
if ($key === false) {
+ − 346
$this->disable[] = $name;
+ − 347
}
+ − 348
}
+ − 349
+ − 350
function transform($text, $format = 'Xhtml')
+ − 351
{
+ − 352
$this->parse($text);
+ − 353
return $this->render($format);
+ − 354
}
+ − 355
+ − 356
function parse($text)
+ − 357
{
+ − 358
$this->source = $text;
+ − 359
+ − 360
$this->tokens = array();
+ − 361
$this->_countRulesTokens = array();
+ − 362
+ − 363
foreach ($this->rules as $name) {
+ − 364
if (! in_array($name, $this->disable)) {
+ − 365
$this->loadParseObj($name);
+ − 366
+ − 367
if (is_object($this->parseObj[$name])) {
+ − 368
$this->parseObj[$name]->parse();
+ − 369
}
32
4d87aad3c4c0
Finished everything on the TODO list (yay!); several CSS cleanups; tons more changes in this commit - see the patch for details
Dan
diff
changeset
+ − 370
// For debugging
4d87aad3c4c0
Finished everything on the TODO list (yay!); several CSS cleanups; tons more changes in this commit - see the patch for details
Dan
diff
changeset
+ − 371
// echo('<p>' . $name . ':</p><pre>'.htmlspecialchars($this->source).'</pre>');
1
+ − 372
}
+ − 373
}
+ − 374
}
+ − 375
+ − 376
function render($format = 'Xhtml')
+ − 377
{
+ − 378
$format = ucwords(strtolower($format));
+ − 379
+ − 380
$output = '';
+ − 381
+ − 382
$in_delim = false;
+ − 383
+ − 384
$key = '';
+ − 385
+ − 386
$result = $this->loadFormatObj($format);
+ − 387
if ($this->isError($result)) {
+ − 388
return $result;
+ − 389
}
78
4df25dfdde63
Modified Text_Wiki parser to fully support UTF-8 strings; several other UTF-8 fixes, international characters seem to work reasonably well now
Dan
diff
changeset
+ − 390
1
+ − 391
if (is_object($this->formatObj[$format])) {
+ − 392
$output .= $this->formatObj[$format]->pre();
+ − 393
}
+ − 394
+ − 395
foreach (array_keys($this->_countRulesTokens) as $rule) {
+ − 396
$this->loadRenderObj($format, $rule);
+ − 397
}
78
4df25dfdde63
Modified Text_Wiki parser to fully support UTF-8 strings; several other UTF-8 fixes, international characters seem to work reasonably well now
Dan
diff
changeset
+ − 398
1
+ − 399
$k = strlen($this->source);
+ − 400
for ($i = 0; $i < $k; $i++) {
+ − 401
+ − 402
$char = $this->source{$i};
+ − 403
+ − 404
if ($in_delim) {
+ − 405
+ − 406
if ($char == $this->delim) {
+ − 407
+ − 408
$key = (int)$key;
+ − 409
$rule = $this->tokens[$key][0];
+ − 410
$opts = $this->tokens[$key][1];
+ − 411
$output .= $this->renderObj[$rule]->token($opts);
+ − 412
$in_delim = false;
+ − 413
+ − 414
} else {
+ − 415
+ − 416
$key .= $char;
+ − 417
+ − 418
}
+ − 419
+ − 420
} else {
+ − 421
+ − 422
if ($char == $this->delim) {
+ − 423
$key = '';
+ − 424
$in_delim = true;
+ − 425
} else {
+ − 426
$output .= $char;
+ − 427
}
+ − 428
}
+ − 429
}
+ − 430
+ − 431
if (is_object($this->formatObj[$format])) {
+ − 432
$output .= $this->formatObj[$format]->post();
+ − 433
}
+ − 434
+ − 435
return $output;
+ − 436
}
+ − 437
+ − 438
function getSource()
+ − 439
{
+ − 440
return $this->source;
+ − 441
}
+ − 442
+ − 443
function getTokens($rules = null)
+ − 444
{
+ − 445
if (is_null($rules)) {
+ − 446
return $this->tokens;
+ − 447
} else {
+ − 448
settype($rules, 'array');
+ − 449
$result = array();
+ − 450
foreach ($this->tokens as $key => $val) {
+ − 451
if (in_array($val[0], $rules)) {
+ − 452
$result[$key] = $val;
+ − 453
}
+ − 454
}
+ − 455
return $result;
+ − 456
}
+ − 457
}
+ − 458
+ − 459
function addToken($rule, $options = array(), $id_only = false)
+ − 460
{
+ − 461
static $id;
+ − 462
if (! isset($id)) {
+ − 463
$id = 0;
+ − 464
} else {
+ − 465
$id ++;
+ − 466
}
+ − 467
+ − 468
settype($options, 'array');
+ − 469
+ − 470
$this->tokens[$id] = array(
+ − 471
0 => $rule,
+ − 472
1 => $options
+ − 473
);
+ − 474
if (!isset($this->_countRulesTokens[$rule])) {
+ − 475
$this->_countRulesTokens[$rule] = 1;
+ − 476
} else {
+ − 477
++$this->_countRulesTokens[$rule];
+ − 478
}
+ − 479
+ − 480
if ($id_only) {
+ − 481
return $id;
+ − 482
} else {
+ − 483
return $this->delim . $id . $this->delim;
+ − 484
}
+ − 485
}
+ − 486
+ − 487
function setToken($id, $rule, $options = array())
+ − 488
{
+ − 489
$oldRule = $this->tokens[$id][0];
+ − 490
$this->tokens[$id] = array(
+ − 491
0 => $rule,
+ − 492
1 => $options
+ − 493
);
+ − 494
if ($rule != $oldRule) {
+ − 495
if (!($this->_countRulesTokens[$oldRule]--)) {
+ − 496
unset($this->_countRulesTokens[$oldRule]);
+ − 497
}
+ − 498
if (!isset($this->_countRulesTokens[$rule])) {
+ − 499
$this->_countRulesTokens[$rule] = 1;
+ − 500
} else {
+ − 501
++$this->_countRulesTokens[$rule];
+ − 502
}
+ − 503
}
+ − 504
}
+ − 505
+ − 506
function loadParseObj($rule)
+ − 507
{
+ − 508
$rule = ucwords(strtolower($rule));
+ − 509
$file = $rule . '.php';
+ − 510
$class = "Text_Wiki_Parse_$rule";
+ − 511
+ − 512
if (! class_exists($class)) {
+ − 513
$loc = $this->findFile('parse', $file);
+ − 514
if ($loc) {
+ − 515
include_once $loc;
+ − 516
} else {
+ − 517
$this->parseObj[$rule] = null;
+ − 518
return $this->error(
+ − 519
"Parse rule '$rule' not found"
+ − 520
);
+ − 521
}
+ − 522
}
+ − 523
345
4ccdfeee9a11
WiP commit for admin panel localization. All modules up to Admin:UserManager (working down the list) are localized except Admin:ThemeManager, which is due for a rewrite
Dan
diff
changeset
+ − 524
$this->parseObj[$rule] = new $class($this);
1
+ − 525
+ − 526
}
+ − 527
+ − 528
function loadRenderObj($format, $rule)
+ − 529
{
+ − 530
$format = ucwords(strtolower($format));
+ − 531
$rule = ucwords(strtolower($rule));
+ − 532
$file = "$format/$rule.php";
+ − 533
$class = "Text_Wiki_Render_$format" . "_$rule";
+ − 534
+ − 535
if (! class_exists($class)) {
+ − 536
$loc = $this->findFile('render', $file);
+ − 537
if ($loc) {
+ − 538
include_once $loc;
+ − 539
} else {
+ − 540
return $this->error(
+ − 541
"Render rule '$rule' in format '$format' not found"
+ − 542
);
+ − 543
}
+ − 544
}
+ − 545
345
4ccdfeee9a11
WiP commit for admin panel localization. All modules up to Admin:UserManager (working down the list) are localized except Admin:ThemeManager, which is due for a rewrite
Dan
diff
changeset
+ − 546
$this->renderObj[$rule] = new $class($this);
1
+ − 547
}
+ − 548
+ − 549
function loadFormatObj($format)
+ − 550
{
+ − 551
$format = ucwords(strtolower($format));
+ − 552
$file = $format . '.php';
+ − 553
$class = "Text_Wiki_Render_$format";
+ − 554
+ − 555
if (! class_exists($class)) {
+ − 556
$loc = $this->findFile('render', $file);
+ − 557
if ($loc) {
+ − 558
include_once $loc;
+ − 559
} else {
+ − 560
return $this->error(
+ − 561
"Rendering format class '$class' not found"
+ − 562
);
+ − 563
}
+ − 564
}
+ − 565
345
4ccdfeee9a11
WiP commit for admin panel localization. All modules up to Admin:UserManager (working down the list) are localized except Admin:ThemeManager, which is due for a rewrite
Dan
diff
changeset
+ − 566
$this->formatObj[$format] = new $class($this);
1
+ − 567
}
+ − 568
+ − 569
function addPath($type, $dir)
+ − 570
{
+ − 571
$dir = $this->fixPath($dir);
+ − 572
if (! isset($this->path[$type])) {
+ − 573
$this->path[$type] = array($dir);
+ − 574
} else {
+ − 575
array_unshift($this->path[$type], $dir);
+ − 576
}
+ − 577
}
+ − 578
+ − 579
function getPath($type = null)
+ − 580
{
+ − 581
if (is_null($type)) {
+ − 582
return $this->path;
+ − 583
} elseif (! isset($this->path[$type])) {
+ − 584
return array();
+ − 585
} else {
+ − 586
return $this->path[$type];
+ − 587
}
+ − 588
}
+ − 589
+ − 590
function findFile($type, $file)
+ − 591
{
+ − 592
$set = $this->getPath($type);
+ − 593
+ − 594
foreach ($set as $path) {
+ − 595
$fullname = $path . $file;
+ − 596
if (file_exists($fullname) && is_readable($fullname)) {
+ − 597
return $fullname;
+ − 598
}
+ − 599
}
+ − 600
+ − 601
return false;
+ − 602
}
+ − 603
+ − 604
function fixPath($path)
+ − 605
{
+ − 606
$len = strlen($this->_dirSep);
+ − 607
+ − 608
if (! empty($path) &&
+ − 609
substr($path, -1 * $len, $len) != $this->_dirSep) {
+ − 610
return $path . $this->_dirSep;
+ − 611
} else {
+ − 612
return $path;
+ − 613
}
+ − 614
}
+ − 615
+ − 616
function &error($message)
+ − 617
{
+ − 618
die($message);
+ − 619
}
+ − 620
+ − 621
function isError(&$obj)
+ − 622
{
371
dc6026376919
Improved compatibility with PostgreSQL and fixed a number of installer bugs; fixed missing "meta" category declaration in language files
Dan
diff
changeset
+ − 623
return ( @get_class($obj) == 'PEAR_Error' );
1
+ − 624
}
+ − 625
}
+ − 626
+ − 627
?>