1<?php 2/** 3 * Data structures used in parsing XML DocBook-based tutorials 4 * 5 * Conversion of DocBook-based tutorials is performed using special 6 * {@link Converter} class methods. By default, these methods simply retrieve 7 * simple rules for replacement of tags and slight re-ordering from the 8 * options.ini file present for every template. 9 * 10 * In future versions, there may be utilization of xslt or other more powerful 11 * protocols. However, for most situations, the power of these classes will 12 * be more than sufficient to handle very complex documentation. 13 * 14 * Note that an entire tutorial is contained in a single parserXMLDocBookTag, 15 * matching the document model for DocBook. The top-level tag, <refentry>, 16 * contains every other tag and all text. 17 * 18 * phpDocumentor :: automatic documentation generator 19 * 20 * PHP versions 4 and 5 21 * 22 * Copyright (c) 2002-2008 Gregory Beaver 23 * 24 * LICENSE: 25 * 26 * This library is free software; you can redistribute it 27 * and/or modify it under the terms of the GNU Lesser General 28 * Public License as published by the Free Software Foundation; 29 * either version 2.1 of the License, or (at your option) any 30 * later version. 31 * 32 * This library is distributed in the hope that it will be useful, 33 * but WITHOUT ANY WARRANTY; without even the implied warranty of 34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 35 * Lesser General Public License for more details. 36 * 37 * You should have received a copy of the GNU Lesser General Public 38 * License along with this library; if not, write to the Free Software 39 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 40 * 41 * @category ToolsAndUtilities 42 * @package phpDocumentor 43 * @subpackage Tutorial 44 * @author Gregory Beaver <cellog@php.net> 45 * @copyright 2002-2008 Gregory Beaver 46 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL 47 * @version CVS: $Id: PackagePageElements.inc 253643 2008-02-24 04:27:54Z ashnazg $ 48 * @tutorial tutorials.pkg 49 * @link http://www.phpdoc.org 50 * @link http://pear.php.net/PhpDocumentor 51 * @since 1.2.0 52 * @todo CS cleanup - change package to PhpDocumentor 53 */ 54/** 55 * Represents <![CDATA[ ]]> sections. 56 * 57 * These sections are interpreted as plain text 58 * 59 * @category ToolsAndUtilities 60 * @package phpDocumentor 61 * @subpackage Tutorial 62 * @author Gregory Beaver <cellog@php.net> 63 * @copyright 2002-2008 Gregory Beaver 64 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL 65 * @version Release: 1.4.4 66 * @tutorial tutorials.pkg 67 * @link http://www.phpdoc.org 68 * @link http://pear.php.net/PhpDocumentor 69 * @todo CS cleanup - change package to PhpDocumentor 70 * @todo CS cleanup - change classname to PhpDocumentor_* 71 */ 72class parserCData extends parserStringWithInlineTags 73{ 74 /** 75 * calls the output conversion 76 * 77 * @param Converter &$c the output converter 78 * @param bool $postprocess if postprocessing is needed 79 * 80 * @return string 81 * @uses Converter::getCData() convert contents to text 82 * @todo CS cleanup - rename to convert for camelCase rule 83 */ 84 function Convert(&$c, $postprocess = true) 85 { 86 $val = $this->value; 87 if ($postprocess) { 88 foreach ($this->value as $key => $value) { 89 if (is_string($value)) { 90 $this->value[$key] = $c->getCData($value); 91 } 92 } 93 } 94 $this->cache = false; 95 $x = parent::Convert($c, false); 96 $this->value = $val; 97 return $x; 98 } 99} 100/** 101 * a standard XML DocBook Tag 102 * 103 * This class is designed to represent all DocBook tags. It is intelligent 104 * enough to understand the <title> tag, and also the <refname> tag for 105 * as title for <refentry> 106 * 107 * @category ToolsAndUtilities 108 * @package phpDocumentor 109 * @subpackage Tutorial 110 * @author Gregory Beaver <cellog@php.net> 111 * @copyright 2002-2008 Gregory Beaver 112 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL 113 * @version Release: 1.4.4 114 * @tutorial tutorials.pkg 115 * @link http://www.phpdoc.org 116 * @link http://pear.php.net/PhpDocumentor 117 * @since 1.2 118 * @todo CS cleanup - change package to PhpDocumentor 119 * @todo CS cleanup - change classname to PhpDocumentor_* 120 * @todo CS cleanup - rename to parserXmlDocBookTag for camelCase rule 121 */ 122class parserXMLDocBookTag extends parserStringWithInlineTags 123{ 124 /** 125 * Attributes from the XML tag 126 * 127 * Format: array(attrname => attrvalue, attrname => attrvalue,...) 128 * @var array 129 */ 130 var $attributes = array(); 131 /** 132 * Name of the tag 133 * @var string 134 */ 135 var $name; 136 /**#@+ 137 * @access private 138 */ 139 /** 140 * @var parserCData 141 */ 142 var $_cdata; 143 /** 144 * @var parserTag 145 */ 146 var $_title; 147 /** 148 * @var parserIdLineTag 149 */ 150 var $_id; 151 /** 152 * Set to <refpurpose> in <refsynopsisdiv> 153 * @var parserTag 154 */ 155 var $_description; 156 /**#@-*/ 157 158 /** 159 * sets up the tag 160 * 161 * @param string $name tag name 162 * 163 * @todo CS cleanup - rename to parserXmlDocBookTag for camelCase rule 164 */ 165 function parserXMLDocBookTag($name) 166 { 167 $this->name = $name; 168 } 169 170 /** 171 * calls the output conversion 172 * 173 * @param Converter &$c the output converter 174 * @param bool $postprocess if postprocessing is needed 175 * 176 * @return string 177 * @uses Converter::TranslateTag() Calls this to enclose the contents of the 178 * DocBook tag based on the values in template options.ini file 179 */ 180 function Convert(&$c, $postprocess = true) 181 { 182 $value = parent::Convert($c, $postprocess); 183 $simvalue = parent::Convert($c, false); 184 foreach ($this->attributes as $a => $v) { 185 $this->attributes[$a] = (is_string($v) ? $v : 186 $v->Convert($c, $postprocess)); 187 } 188 if (isset($this->_title)) { 189 list($this->attributes,$value) = $c->ConvertTitle($this->name, 190 $this->attributes, $this->_title->Convert($c, $postprocess), $value); 191 } 192 return $c->TranslateTag($this->name, $this->attributes, $value, $simvalue); 193 } 194 195 /** 196 * Begin a new CData section 197 * 198 * @return void 199 * @see addCData() 200 */ 201 function startCData() 202 { 203 $this->_cdata = new parserCData; 204 } 205 206 /** 207 * Adds {@link $_cdata} to {@link $value} 208 * 209 * @return void 210 */ 211 function endCData() 212 { 213 $this->value[] = $this->_cdata; 214 unset($this->_cdata); 215 } 216 217 /** 218 * Retrieve either the table of contents index, 219 * or the location that the TOC will go 220 * 221 * @param false|integer $state either an index of the {@}toc} tag in $this->value 222 * or false, if the next index value of $this->value 223 * is needed 224 * 225 * @return int 226 * @see setTOC() 227 */ 228 function getTOC($state = false) 229 { 230 if ($state !== false) { 231 return $this->value[$state]; 232 } 233 return count($this->value); 234 } 235 236 /** 237 * sets the TOC value 238 * 239 * @param integer $state index of the TOC in $this->value 240 * @param parserTocInlineTag $val tag value 241 * 242 * @return void 243 */ 244 function setTOC($state, $val) 245 { 246 $this->value[$state] = $val; 247 } 248 249 /** 250 * add a word to CData 251 * 252 * @param string $word word to add 253 * 254 * @return void 255 */ 256 function addCData($word) 257 { 258 $this->_cdata->add($word); 259 } 260 261 /** 262 * Add an xml tag attribute name="value" pair 263 * 264 * if the attribute is id, value must be a {@link parserIdInlineTag} 265 * 266 * @param string $name attribute name 267 * @param string|parserIdInlineTag $value value of attribute 268 * 269 * @return void 270 */ 271 function addAttribute($name, $value) 272 { 273 $this->attributes[$name] = $value; 274 if ($name == 'id') { 275 // fix 1153593 276 if (is_string($value)) { 277 addWarning(PDERROR_ID_MUST_BE_INLINE, $this->name, $value, 278 $this->name, $value); 279 } else { 280 $this->setId($value); 281 } 282 } 283 } 284 285 /** 286 * Set the title of a DocBook tag section. 287 * 288 * For most DocBook tags, the title is represented with a <title></title> 289 * tag pair. The <refentry> top-level tag is a little different. Instead 290 * of using <title></title>, phpDocumentor uses the contents of the 291 * <refname> tag in the <refnamediv> tag 292 * 293 * @param parserXMLDocBookTag $title the title element 294 * 295 * @return void 296 */ 297 function setTitle($title) 298 { 299 $this->_title = $title; 300 } 301 302 /** 303 * If the id attribute is present, this method will set its id 304 * 305 * @param parserIdInlineTag $id the id value 306 * 307 * @return void 308 */ 309 function setId($id) 310 { 311 $this->_id = $id; 312 } 313 314 /** 315 * Return converter-specific formatting of ID. 316 * 317 * Passes $c to {@link parserIdInlineTag::Convert()} 318 * 319 * @param Converter &$c the output converter 320 * 321 * @return string 322 */ 323 function getId(&$c) 324 { 325 if ($this->_id) { 326 return trim($this->_id->Convert($c)); 327 } 328 } 329 330 /** 331 * Determine whether the docbook element has a title 332 * 333 * @return boolean 334 */ 335 function hasTitle() 336 { 337 return isset($this->_title); 338 } 339 340 /** 341 * Retrieve Converter-specific formatting of the title of this element 342 * 343 * @param Converter &$c the output converter 344 * 345 * @return string 346 */ 347 function getTitle(&$c) 348 { 349 if ($this->name == 'refentry') { 350 foreach ($this->value as $tag) { 351 if (is_object($tag) && $tag->name == 'refnamediv') { 352 return $tag->getTitle($c); 353 } 354 } 355 } 356 if ($this->name == 'refnamediv') { 357 foreach ($this->value as $tag) { 358 if (is_object($tag) && is_a($tag, 'parserXMLDocBookTag') 359 && $tag->name == 'refname') { 360 $t = new parserStringWithInlineTags; 361 foreach ($tag->value as $val) { 362 $t->add($val); 363 } 364 $this->_title = $t; 365 } 366 if (is_object($tag) && is_a($tag, 'parserXMLDocBookTag') 367 && $tag->name == 'refpurpose') { 368 $t = new parserStringWithInlineTags; 369 foreach ($tag->value as $val) { 370 $t->add($val); 371 } 372 $this->_description = $t; 373 } 374 } 375 } 376 if (isset($this->_title)) { 377 return $this->_title->Convert($c); 378 } 379 if (is_object($this->value[0]) && is_a($tag, 'parserXMLDocBookTag')) { 380 return $this->value[0]->getTitle($c); 381 } 382 if (isset($this->value[1])) { 383 if (is_object($this->value[1]) && is_a($tag, 'parserXMLDocBookTag')) { 384 return $this->value[1]->getTitle($c); 385 } 386 } 387 return ''; 388 } 389 390 /** 391 * Retrieve the contents of a subsection 392 * 393 * This method uses the $_id members of nested docbook tags to retrieve 394 * the section defined by $subsection 395 * 396 * @param Converter &$c the output converter 397 * @param string $subsection converter-specific subsection 398 * 399 * @return bool|string 400 */ 401 function getSubsection(&$c, $subsection) 402 { 403 if (!is_object($this->_id)) { 404 return false; 405 } 406 $search = phpDocumentor_clone($this->_id); 407 if (is_string($this->_id)) { 408 return false; 409 } 410 if (phpDocumentor_get_class($search) != 'parseridinlinetag') { 411 return false; 412 } 413 $search->id = $subsection; 414 foreach ($this->value as $el) { 415 if (phpDocumentor_get_class($el) == 'parserxmldocbooktag') { 416 if ($el->getId($c) == $search->Convert($c)) { 417 return $el; 418 } elseif ($a = $el->getSubsection($c, $subsection)) { 419 return $a; 420 } 421 } 422 } 423 return false; 424 } 425 426 /** 427 * Add contents to this tag. 428 * 429 * There are four kinds of data in a DocBook tutorial: 430 * 1. <b>tags</b> - normal tags like <refentry> 431 * 2. <b>entities</b> - normal entities like ” 432 * 3. <b><![CDATA[</b> - character data that should not be interpreted, 433 * like <programlisting> contents 434 * 4. <b>text</b> - normal non-markup text 435 * 436 * All four kinds of data are added here 437 * 438 * @param parserEntity|parserCData|parserXMLDocBookTag|string $el nested tag, 439 * entity, or text 440 * 441 * @return mixed 442 */ 443 function add($el) 444 { 445 if (is_string($el)) { 446 return parent::add($el); 447 } 448 if (phpDocumentor_get_class($el) == 'parserxmldocbooktag') { 449 if ($el->name == 'title') { 450 $this->setTitle($el); 451 } else { 452 return parent::add($el); 453 } 454 } else { 455 return parent::add($el); 456 } 457 } 458} 459 460/** 461 * a standard entity like ” 462 * 463 * This class is designed to represent all DocBook entities. 464 * 465 * @category ToolsAndUtilities 466 * @package phpDocumentor 467 * @subpackage Tutorial 468 * @author Gregory Beaver <cellog@php.net> 469 * @copyright 2002-2008 Gregory Beaver 470 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL 471 * @version Release: 1.4.4 472 * @tutorial tutorials.pkg 473 * @link http://www.phpdoc.org 474 * @link http://pear.php.net/PhpDocumentor 475 * @since 1.2 476 * @todo CS cleanup - change package to PhpDocumentor 477 * @todo CS cleanup - change classname to PhpDocumentor_* 478 */ 479class parserEntity 480{ 481 /** 482 * sets up the entity 483 * 484 * @param string $name entity name 485 */ 486 function parserEntity($name) 487 { 488 $this->value = $name; 489 } 490 491 /** 492 * calls the output conversion 493 * 494 * @param Converter &$c the output converter 495 * @param bool $postprocess if postprocessing is needed 496 * 497 * @return string 498 * @uses Converter::TranslateEntity() convert contents to text 499 * @todo CS cleanup - rename to convert for camelCase rule 500 */ 501 function Convert(&$c, $postprocess = true) 502 { 503 if ($postprocess) { 504 return $c->TranslateEntity($this->value); 505 } else { 506 $trans_tbl = get_html_translation_table(HTML_ENTITIES); 507 $trans_tbl = array_flip($trans_tbl); 508 $ret = strtr('&'.$this->value.';', $trans_tbl); 509 return $ret; 510 } 511 } 512} 513?> 514