openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

XhtmlRenderer.class.php (10533B)


      1 <?php
      2 
      3 namespace wikiparser\renderer;
      4 use cms\base\Configuration;
      5 use wikiparser\model\DefinitionItemElement;
      6 use DefinitionListEntryElement;
      7 use DefinitionListItemElement;
      8 use File;
      9 use Geshi;
     10 use wikiparser\model\LineBreakElement;
     11 use wikiparser\model\LinkElement;
     12 use logger\Logger;
     13 use wikiparser\model\RawElement;
     14 use util\Text;
     15 use wikiparser\model\TextElement;
     16 
     17 /**
     18  * Dokument-Objekt.<br>
     19  * Diese Objekt verk�rpert das Root-Objekt in einem DOM-Baum.<br>
     20  * <br>
     21  * Dieses Objekt kann Text parsen und seine Unterobjekte selbst erzeugen.<br>
     22  *
     23  * @author Jan Dankert, $Author$
     24  * @version $Revision$
     25  * @package openrat.text
     26  */
     27 class XhtmlRenderer
     28 {
     29 	var $linkedObjectIds = array();
     30 	var $encodeHtml = false;
     31 
     32 	/**
     33 	 * Fu�noten.
     34 	 *
     35 	 * @var Array
     36 	 */
     37 	var $footnotes = array();
     38 
     39 
     40 	/**
     41 	 * Rendert ein Dokument-Element.
     42 	 *
     43 	 * @param Object $child Element
     44 	 * @return String
     45 	 */
     46 	function renderElement($child)
     47 	{
     48 		$attr = array();
     49 		$val = '';
     50 		$praefix = '';
     51 		$suffix = '';
     52 		$empty = false;
     53 
     54 		if (count($child->children) > 0) {
     55 			$subChild1 = $child->children[0];
     56 
     57 			if (!empty($subChild1->class))
     58 				$attr['class'] = $subChild1->class;
     59 
     60 			if (!empty($subChild1->style))
     61 				$attr['style'] = $subChild1->style;
     62 
     63 			if (!empty($subChild1->title))
     64 				$attr['title'] = $subChild1->title;
     65 		}
     66 
     67 		switch (strtolower(get_class($child))) {
     68 			case 'tableofcontentelement':
     69 				$tag = 'p';
     70 				foreach ($this->children as $h) {
     71 					if (strtolower(get_class($h)) == 'headlineelement') {
     72 						$child->children[] = new RawElement(str_repeat('&nbsp;&nbsp;', $h->level));
     73 						$t = new TextElement($h->getText());
     74 						$l = new LinkElement();
     75 						$l->fragment = $h->getName();
     76 						$l->children[] = $t;
     77 						$child->children[] = $l;
     78 						$child->children[] = new LineBreakElement();
     79 					}
     80 				}
     81 				break;
     82 
     83 			case 'rawelement':
     84 				$tag = '';
     85 				$val = $child->src;
     86 
     87 				break;
     88 
     89 			case 'textelement':
     90 				$tag = '';
     91 //						$tag = 'span';
     92 
     93 				$val = $child->text;
     94 				if ($this->encodeHtml)
     95 					$val = Text::encodeHtml($val);
     96 				$val = Text::replaceHtmlChars($val);
     97 				break;
     98 
     99 			case 'footnoteelement':
    100 				$tag = 'a';
    101 				$attr['href'] = '#footnote';
    102 
    103 				$title = '';
    104 				foreach ($child->children as $c)
    105 					$title .= $this->renderElement($c);
    106 				$attr['title'] = strip_tags($title);
    107 
    108 				$nr = 1;
    109 				foreach ($this->footnotes as $fn)
    110 					if (strtolower(get_class($fn)) == 'linebreakelement')
    111 						$nr++;
    112 
    113 				$val = $nr;
    114 				$footnoteConfig = Configuration::subset(['editor','footnote']);
    115 				if ($footnoteConfig->is('bracket'))
    116 					$val = '(' . $nr . ')';
    117 				if ($footnoteConfig->is('sup'))
    118 					$val = '<sup><small>' . $nr . '</small></sup>';
    119 
    120 
    121 				if ($nr == 1) {
    122 					$this->footnotes[] = new RawElement('&mdash;');
    123 					$le = new LinkElement();
    124 					$le->name = "footnote";
    125 					$this->footnotes[] = $le;
    126 					$this->footnotes[] = new RawElement('&mdash;');
    127 				}
    128 				$this->footnotes[] = new LineBreakElement();
    129 				$this->footnotes[] = new RawElement($val);
    130 				$this->footnotes[] = new RawElement(' ');
    131 				foreach ($child->children as $c)
    132 					$this->footnotes[] = $c;
    133 
    134 				$child->children = array();
    135 
    136 				break;
    137 
    138 			case 'codeelement':
    139 
    140 				if (empty($child->language))
    141 					// Wenn keine Sprache verf�gbar, dann ein einfaches PRE-Element erzeugen.
    142 					$tag = 'pre';
    143 				else {
    144 					// Wenn Sprache verf�gbar, dann den GESHI-Parser bem�hen.
    145 					$tag = '';
    146 					$source = '';
    147 					foreach ($child->children as $c)
    148 						if (strtolower(get_class($c)) == 'textelement')
    149 							$source .= $c->text . "\n";
    150 					$child->children = array();
    151 					require_once('./geshi/geshi.php');
    152 					$geshi = new Geshi($source, $child->language);
    153 					$val = $geshi->parse_code();
    154 				}
    155 				break;
    156 
    157 			case 'quoteelement':
    158 				$tag = 'blockquote';
    159 				break;
    160 
    161 
    162 			case 'paragraphelement':
    163 				$tag = 'p';
    164 				break;
    165 
    166 			case 'speechelement':
    167 				$tag = 'cite';
    168 
    169 				// Danke an: http://www.apostroph.de/tueddelchen.php
    170 				//TODO: Abh�ngigkeit von Spracheinstellung implementieren.
    171 				$language = 'de';
    172 				switch ($language) {
    173 					case 'de': // deutsche Notation
    174 						$praefix = '&bdquo;';
    175 						$suffix = '&ldquo;';
    176 						break;
    177 					case 'fr':
    178 						$praefix = '&laquo;';
    179 						$suffix = '&raquo;';
    180 						break;
    181 					default: // englische Notation
    182 						$praefix = '&ldquo;';
    183 						$suffix = '&rdquo;';
    184 				}
    185 
    186 				$htmlConfig = Configuration::subset(['editor', 'html']);
    187 				if ($htmlConfig->is('override_speech')) {
    188 					$praefix = $htmlConfig->get('override_speech_open');
    189 					$suffix  = $htmlConfig->get('override_speech_close');
    190 				}
    191 				break;
    192 
    193 			case 'linebreakelement':
    194 				$tag = 'br';
    195 				$empty = true;
    196 				break;
    197 
    198 			case 'linkelement':
    199 				$tag = 'a';
    200 				if (!empty($child->name))
    201 					$attr['name'] = $child->name;
    202 				else
    203 					$attr['href'] = htmlspecialchars($child->getUrl());
    204 
    205 				if (Object::available($child->objectId)) {
    206 					$file = new File($child->objectId);
    207 					$file->load();
    208 					$attr['title'] = $file->description;
    209 					unset($file);
    210 				}
    211 				break;
    212 
    213 			case 'imageelement':
    214 				$empty = true;
    215 				$attr['alt'] = '';
    216 
    217 				if (!Object::available($child->objectId)) {
    218 					$tag = '';
    219 				} elseif (empty($attr['title'])) {
    220 					$tag = 'img';
    221 					$attr['src'] = $child->getUrl();
    222 					$attr['border'] = '0';
    223 
    224 					// Breite/H�he des Bildes bestimmen.
    225 					$image = new File($child->objectId);
    226 
    227 					$image->load();
    228 					$attr['alt'] = $image->name;
    229 					$attr['title'] = $image->description;
    230 
    231 					$image->getImageSize();
    232 					$attr['width'] = $image->width;
    233 					$attr['height'] = $image->height;
    234 					unset($image);
    235 				} else {
    236 					$tag = 'dl';
    237 
    238 					if (empty($attr['class']))
    239 						$attr['class'] = "image";
    240 
    241 					$child->children = array();
    242 					$dt = new DefinitionListItemElement();
    243 					$dt->children[] = new TextElement('(image)');
    244 					$dt->children[] = $child;
    245 					$child->children[] = $dt;
    246 
    247 					$dd = new DefinitionListEntryElement();
    248 					$dd->children[] = new TextElement('(image)');
    249 					$dd->children[] = new TextElement($attr['title']);
    250 					$child->children[] = $dd;
    251 				}
    252 				break;
    253 
    254 			case 'strongelement':
    255 				$tag = 'strong';
    256 				break;
    257 
    258 			case 'emphaticelement':
    259 				$tag = 'em';
    260 				break;
    261 
    262 			case 'insertedelement':
    263 				$tag = 'ins';
    264 				break;
    265 
    266 			case 'removedelement':
    267 				$tag = 'del';
    268 				break;
    269 
    270 			case 'headlineelement':
    271 				$tag = 'h' . $child->level;
    272 
    273 				$l = new LinkElement();
    274 				$l->name = $child->getName();
    275 				$child->children[] = $l;
    276 
    277 				break;
    278 
    279 			case 'tableelement':
    280 				$tag = 'table';
    281 				break;
    282 
    283 			case 'tablelineelement':
    284 				$tag = 'tr';
    285 				break;
    286 
    287 			case 'definitionlistelement':
    288 				$items = $child->children;
    289 				$newChildren = array();
    290 				foreach ($items as $item) {
    291 					$def = new DefinitionItemElement();
    292 					$def->key = $item->key;
    293 					$item->key = '';
    294 					$newChildren[] = $def;
    295 					$newChildren[] = $item;
    296 				}
    297 //						Html::debug($newChildren,'Children-neu');
    298 				$child->children = $newChildren;
    299 				$tag = 'dl';
    300 				break;
    301 
    302 			case 'definitionitemelement':
    303 				if (!empty($child->key)) {
    304 					$tag = 'dt';
    305 					$val = $child->key;
    306 				} else {
    307 					$tag = 'dd';
    308 				}
    309 				break;
    310 
    311 			case 'tablecellelement':
    312 				if ($child->isHeading)
    313 					$tag = 'th'; else $tag = 'td';
    314 
    315 				if ($child->rowSpan > 1)
    316 					$attr['rowspan'] = $child->rowSpan;
    317 				if ($child->colSpan > 1)
    318 					$attr['colspan'] = $child->colSpan;
    319 				break;
    320 
    321 			case 'listelement':
    322 				$tag = 'ul';
    323 				break;
    324 
    325 			case 'teletypeelement':
    326 				$tag = 'code';
    327 				break;
    328 
    329 			case 'numberedlistelement':
    330 				$tag = 'ol';
    331 				break;
    332 
    333 			case 'listentryelement':
    334 				$tag = 'li';
    335 				break;
    336 
    337 			case 'macroelement':
    338 
    339 				$className = ucfirst($child->name);
    340 				$fileName = './dynamicClasses/' . $className . '.class.php';
    341 				if (is_file($fileName)) {
    342 					// Fuer den Fall, dass eine Dynamic-Klasse mehrmals pro Vorlage auftritt
    343 					if (!class_exists($className))
    344 						require($fileName);
    345 
    346 					if (class_exists($className)) {
    347 						$dynEl = new $className;
    348 						$dynEl->page = &$this->page;
    349 
    350 						if (method_exists($dynEl, 'execute')) {
    351 							$dynEl->objectid = $this->page->objectid;
    352 							$dynEl->page = &$this->page;
    353 
    354 							foreach ($child->attributes as $param_name => $param_value) {
    355 								if (isset($dynEl->$param_name))
    356 									$dynEl->$param_name = $param_value;
    357 							}
    358 
    359 							$dynEl->execute();
    360 							$val = $dynEl->getOutput();
    361 						} else {
    362 							Logger::warn('element:' . $this->element->name . ', ' .
    363 								'class:' . $className . ', no method: execute()');
    364 						}
    365 					} else {
    366 						Logger::warn('element:' . $this->element->name . ', ' .
    367 							'class not found:' . $className);
    368 					}
    369 				} else {
    370 					Logger::warn('element:' . $this->element->name . ', ' .
    371 						'file not found:' . $fileName);
    372 				}
    373 
    374 				// Wenn HTML-Ausgabe, dann Sonderzeichen in HTML �bersetzen
    375 				if ($this->page->mimeType() == 'text/html')
    376 					$inhalt = Text::encodeHtmlSpecialChars($inhalt);
    377 
    378 				break;
    379 
    380 
    381 			default:
    382 
    383 				$tag = 'unknown-element';
    384 				$attr['class'] = strtolower(get_class($child));
    385 				break;
    386 		}
    387 
    388 		$val .= $praefix;
    389 		foreach ($child->children as $c) {
    390 			$val .= $this->renderElement($c);
    391 		}
    392 
    393 		$val .= $suffix;
    394 //				echo "text:$val";
    395 		return $this->renderHtmlElement($tag, $val, $empty, $attr);
    396 
    397 	}
    398 
    399 
    400 	/**
    401 	 * Erzeugt ein HTML-Element.
    402 	 *
    403 	 * @param String $tag Name des Tags
    404 	 * @param String $value Inhalt
    405 	 * @param boolean $empty abk�rzen, wenn Inhalt leer ("<... />")
    406 	 * @param Array $attr Attribute als Array<String,String>
    407 	 * @return String
    408 	 */
    409 	function renderHtmlElement($tag, $value, $empty, $attr = array())
    410 	{
    411 		if ($tag == '')
    412 			return $value;
    413 
    414 		$val = '<' . $tag;
    415 		foreach ($attr as $attrName => $attrInhalt) {
    416 			$val .= ' ' . $attrName . '="' . $attrInhalt . '"';
    417 		}
    418 
    419 		if ($value == '' && $empty) {
    420 			// Inhalt ist leer, also Kurzform verwenden.
    421 			// Die Kurzform ist abh�ngig vom Rendermode.
    422 			// SGML=<tag>
    423 			// XML=<tag />
    424 			if (Configuration::get(['editor','html','rendermode']) == 'xml') {
    425 				$val .= ' />';
    426 				return $val;
    427 			} else {
    428 				$val .= '>';
    429 				return $val;
    430 			}
    431 		}
    432 
    433 		$val .= '>' . $value . '</' . $tag . '>';
    434 		return $val;
    435 	}
    436 
    437 
    438 	/**
    439 	 * Rendering des Dokumentes.<br>
    440 	 *
    441 	 * @return String
    442 	 */
    443 	function render()
    444 	{
    445 		$this->renderedText = '';
    446 		$this->footnotes = array();
    447 
    448 		foreach ($this->children as $child)
    449 			$this->renderedText .= $this->renderElement($child);
    450 
    451 		foreach ($this->footnotes as $child)
    452 			$this->renderedText .= $this->renderElement($child);
    453 
    454 		return $this->renderedText;
    455 	}
    456 }
    457 
    458 ?>