Simplewiki 1
|
00001 <?php 00008 #==========================================================================# 00009 #-----------------------------[ EMITTER ]----------------------------------# 00010 #==========================================================================# 00011 00016 // generates the HTML; other emitters could be substituted 00017 class Muster_SimpleWiki_Emitter 00018 { 00020 00021 protected $_dom; 00023 protected $_rules; 00025 protected $_link_re; 00027 protected $_image_re; 00029 protected $_blocktags = // could be replaced or changed by client 00030 array 00031 ( 00032 'div', 'blockquote', # division, blockquote 00033 'table', 'thead', 'tbody', 'tr', 'td', 'th', 'tfoot', 'caption', # table 00034 'ul', 'ol', 'li', 'dl', 'dt', 'dd', # lists 00035 'dlmodule','dlwidget','dlsettings','dlmarker' #dlml 00036 ); 00039 00040 protected $_class_callouts = array(); 00042 protected $_property_callouts = array(); 00044 protected $_macro_callouts = array(); 00046 protected $_symlinks = array(); 00048 protected $_symlink_handler; 00050 protected $_rawlink_handler; 00052 protected $_charfilter_handler; 00054 protected $_events = array(); 00056 protected $_blockdef_handler; 00064 public function __construct() 00065 { 00066 $this->set_rules(); 00067 $this->set_re($this->_rules); 00068 } 00069 #----------------------------------[ init ]-----------------------------------------# 00070 00073 protected function set_rules() 00074 { 00075 $rules = new StdClass(); 00076 $proto = 'http[s]?|ftp|nntp|news|telnet|file|irc'; 00077 $rules->extern = "(?P<external_address>(?P<external_proto>$proto) 00078 :\/\/(?P<external_selector>\S+\w))"; 00079 $rules->mail = "(?P<external_mailaddress>(?P<external_mailproto>mailto) 00080 :(?P<external_mailselector>\S+\w))"; 00081 $rules->symlink = ' 00082 (?P<internal_address> (?P<symlink>[A-Z][a-zA-Z-]+) : 00083 (?P<internal_selector> [^`\s]+)(?P<internal_version>`\S+)?) 00084 '; 00085 $rules->anchor = ' 00086 (?P<anchor>\#[a-zA-Z][\w-]*) 00087 '; 00088 $rules->rawlink = ' 00089 (?P<rawlink>\S*) 00090 '; 00091 $this->_rules = $rules; 00092 } 00096 protected function set_re($rules) 00097 { 00098 $this->_link_re = '/' . implode('|',array($rules->extern,$rules->mail,$rules->symlink,$rules->anchor,$rules->rawlink)) . '/x'; 00099 $this->_image_re = '/' . implode('|',array($rules->extern,$rules->symlink,$rules->rawlink)) . '/x'; 00100 } 00107 public function emit($dom) // main method 00108 { 00109 $this->_dom = $dom; 00110 return $this->emit_node($dom); 00111 } 00116 protected function emit_node($node) // controller 00117 { 00118 $emit = '_' . $node->type . '_emit'; 00119 return $this->$emit($node); 00120 } 00125 public function emit_children($node) 00126 { 00127 if (empty($node->children)) return ''; 00128 $children = $node->children; 00129 $childoutput = array(); 00130 foreach ($children as $child) 00131 { 00132 $childoutput[] = $this->emit_node($child); 00133 } 00134 return implode('',$childoutput); 00135 } 00138 public function emit_node_text($node) 00139 { 00140 if ($node->type == SimpleWiki_DocNode::TEXT) 00141 return $node->textcontent; 00142 else 00143 return $this->emit_children_text($node); 00144 } 00148 protected function emit_children_text($node) 00149 { 00150 if (empty($node->children)) return ''; 00151 $children = $node->children; 00152 $childoutput = array(); 00153 foreach ($children as $child) 00154 { 00155 $childoutput[] = $this->emit_node_text($child); 00156 } 00157 return implode(' ',$childoutput); 00158 } 00161 00162 public function symlinks() 00163 { 00164 return $this->_symlinks; 00165 } 00167 public function symlink_handler() 00168 { 00169 return $this->_symlink_handler; 00170 } 00172 public function blocktags($blocktaglist = NULL) 00173 { 00174 if (!is_null($blocktaglist)) 00175 $this->_blocktags = $blocktaglist; 00176 return $this->_blocktags; 00177 } 00179 #========================[ callout handling ]=======================================# 00180 00186 public function register_events($callbacks) 00187 { 00188 $events = $this->_events; 00189 foreach ($callbacks as $eventname => $callback) 00190 { 00191 if (!isset($events[$eventname])) 00192 { 00193 $events[$eventname] = array(); 00194 } 00195 $events[$eventname][] = $callback; 00196 } 00197 $this->_events = $events; 00198 } 00201 public function register_symlinks($symlinks) 00202 { 00203 $symlinklist = $this->_symlinks; 00204 foreach ($symlinks as $symlink => $value) { 00205 $symlinklist[$symlink] = $value; 00206 } 00207 $this->_symlinks = $symlinklist; 00208 } 00212 public function register_symlink_handler($handler) 00213 { 00214 $this->_symlink_handler = $handler; 00215 } 00219 public function register_charfilter_handler($handler) 00220 { 00221 $this->_charfilter_handler = $handler; 00222 } 00226 public function register_rawlink_handler($handler) 00227 { 00228 $this->_rawlink_handler = $handler; 00229 } 00233 public function register_class_callouts($callouts) 00234 { 00235 // ['nodetype']['class']=>$methodref 00236 $calloutslist = $this->_class_callouts; 00237 foreach ($callouts as $nodetype => $classcallouts) 00238 { 00239 if (empty($calloutlist[$nodetype])) 00240 { 00241 $calloutlist[$nodetype] = $callouts[$nodetype]; 00242 } 00243 else 00244 { 00245 $classcallouts = $callouts[$nodetype]; 00246 foreach($classcallouts as $class =>$methodref) 00247 { 00248 $calloutlist[$nodetype][$class] = $methodref; 00249 } 00250 } 00251 } 00252 $this->_class_callouts = $calloutlist; 00253 } 00257 public function register_property_callouts($callouts) 00258 { 00259 // ['nodetype']['property']=>$methodref 00260 $calloutslist = $this->_property_callouts; 00261 foreach ($callouts as $nodetype => $propertycallouts) 00262 { 00263 if (empty($calloutlist[$nodetype])) 00264 { 00265 $calloutlist[$nodetype] = $callouts[$nodetype]; 00266 } 00267 else 00268 { 00269 $propertycallouts = $callouts[$nodetype]; 00270 foreach($propertycallouts as $class =>$methodref) 00271 { 00272 $calloutlist[$nodetype][$class] = $methodref; 00273 } 00274 } 00275 } 00276 $this->_property_callouts = $calloutlist; 00277 } 00280 public function register_macro_callouts($callouts) 00281 { 00282 // ['macroname']=>$methodref 00283 $calloutlist = $this->_macro_callouts; 00284 foreach ($callouts as $macroname => $methodref) 00285 { 00286 $calloutlist[$macroname] = $methodref; 00287 } 00288 $this->_macro_callouts = $calloutlist; 00289 } 00294 public function register_blockdef_handler($handler) 00295 { 00296 $this->_blockdef_handler = $handler; 00297 } 00299 #---------------------------[trigger callouts]-------------------------------------# 00300 00306 protected function expand_symlink($node) 00307 { 00308 $symlinks = $this->_symlinks; 00309 if (isset($symlinks[$node->linkparts->symlink])) 00310 $node->linkparts->symlinkpath = $symlinks[$node->linkparts->symlink]; 00311 elseif (isset($this->_symlink_handler)) 00312 $node = call_user_func($this->_symlink_handler,$node); 00313 else { 00314 $node->unknown = TRUE; 00315 $node->linkparts->symlinkpath = $node->linkparts->symlink . ':'; // stub 00316 } 00317 return $node; 00318 } 00324 protected function expand_rawlink($node) 00325 { 00326 if (isset($this->_rawlink_handler)) 00327 $node = call_user_func($this->_rawlink_handler,$node); 00328 else { 00329 $node->unknown = TRUE; 00330 $node->linkparts->rawlinkaddress = $node->linkparts->rawlink; // stub 00331 } 00332 return $node; 00333 } 00339 protected function call_macro($node) 00340 { 00341 $callbacks = $this->_macro_callouts; 00342 if (isset($callbacks[$node->macroname])) 00343 { 00344 $node = call_user_func($callbacks[$node->macroname],$node); 00345 $node->processed = TRUE; 00346 } 00347 return $node; 00348 } 00353 protected function call_classes($node) 00354 { 00355 $callbacks = isset($this->_class_callouts[$node->type])?$this->_class_callouts[$node->type]:NULL; 00356 if (!empty($callbacks)) 00357 { 00358 $classes = !empty($node->decoration->classes)?$node->decoration->classes:NULL; 00359 if (!empty($classes)) 00360 { 00361 foreach ($classes as $class) 00362 { 00363 $callback = isset($callbacks[$class])?$callbacks[$class]:NULL; 00364 if ($callback) 00365 { 00366 $node = call_user_func($callback,$node); 00367 } 00368 } 00369 } 00370 } 00371 return $node; 00372 } 00378 protected function call_properties($node) 00379 { 00380 $callbacks = isset($this->_property_callouts[$node->type])?$this->_property_callouts[$node->type]:NULL; 00381 if (!empty($callbacks)) 00382 { 00383 $properties = !empty($node->decoration->properties)?$node->decoration->properties:NULL; 00384 if (!empty($properties)) 00385 { 00386 foreach ($properties as $propertyindex => $property) 00387 { 00388 $callback = isset($callbacks[$propertyindex])?$callbacks[$propertyindex]:NULL; 00389 if ($callback) 00390 { 00391 $node = call_user_func($callback,$node); 00392 } 00393 } 00394 } 00395 } 00396 return $node; 00397 } 00404 protected function call_event($event,$node) 00405 { 00406 $events = isset($this->_events[$event])?$this->_events[$event]:NULL; 00407 if (!empty($events)) { 00408 foreach ($events as $callback) { 00409 $node = call_user_func($callback,$node); 00410 } 00411 } 00412 return $node; 00413 } 00415 #--------------------------------[ utilities ]---------------------------------------# 00416 00417 /* protected function get_value($value,$default) 00418 { 00419 return isset($value)? $value: $default; 00420 } 00421 */ 00428 protected function prepare_image_node($node) 00429 { 00430 # symlink for src 00431 if (!empty($node->linkparts->symlink)) { 00432 $node = $this->expand_symlink($node); 00433 $node->decoration->attributes['src'] = 00434 $node->linkparts->symlinkpath . $node->linkparts->internalselector; 00435 $node->decoration->attributedelimiters['src'] = '"'; 00436 } 00437 # external address for src 00438 else { 00439 $node->decoration->attributes['src'] = 00440 !empty($node->linkparts->externaladdress)?$node->linkparts->externaladdress:NULL; 00441 $node->decoration->attributedelimiters['src'] = '"'; 00442 } 00443 # alt attribute 00444 // caption, or... 00445 if ($node->caption) { 00446 $node->decoration->attributes['alt'] = $this->char_filter($node->caption,$node); 00447 $node->decoration->attributedelimiters['alt'] = '"'; 00448 } 00449 // ... target. 00450 elseif ($node->target) 00451 { 00452 $node->decoration->attributes['alt'] = $this->char_filter($node->target,$node); 00453 $node->decoration->attributedelimiters['alt'] = '"'; 00454 } 00455 # title attribute 00456 if (!empty($node->title)) { 00457 $node->decoration->attributes['title'] = $node->title; 00458 $node->decoration->attributedelimiters['title'] = '"'; 00459 } 00460 # standard prepare node... 00461 $node = $this->prepare_node($node); 00462 return $node; 00463 } 00471 protected function prepare_link_node($node) 00472 { 00473 $attributename = 'href'; 00474 if (!empty($node->linkparts->anchor)) { 00475 if (empty($node->caption)) { 00476 $attributename = 'name'; 00477 $node->linkparts->anchor = substr($node->linkparts->anchor,1); 00478 $node->decoration->attributes[$attributename] = $node->linkparts->anchor; 00479 $node->decoration->attributedelimiters[$attributename] = '"'; 00480 } else { 00481 $node->linkparts->symlink = 'Anchor'; 00482 $node = $this->expand_symlink($node); 00483 $node->decoration->attributes[$attributename] = $node->linkparts->symlinkpath . $node->linkparts->anchor; 00484 $node->decoration->attributedelimiters[$attributename] = '"'; 00485 } 00486 } 00487 elseif (!empty($node->linkparts->symlink)) { 00488 $node = $this->expand_symlink($node); 00489 $node->decoration->attributes[$attributename] = 00490 $node->linkparts->symlinkpath . (!empty($node->linkparts->internalselector)?$node->linkparts->internalselector:''); 00491 $node->decoration->attributedelimiters[$attributename] = '"'; 00492 } 00493 elseif (!empty($node->linkparts->externaladdress)) { 00494 $node->decoration->attributes[$attributename] = 00495 !empty($node->linkparts->externaladdress)?$node->linkparts->externaladdress:NULL; 00496 $node->decoration->attributedelimiters[$attributename] = '"'; 00497 } 00498 else { 00499 $node = $this->expand_rawlink($node); 00500 $node->decoration->attributes[$attributename] = 00501 !empty($node->linkparts->rawlinkaddress)?$node->linkparts->rawlinkaddress:NULL; 00502 $node->decoration->attributedelimiters[$attributename] = '"'; 00503 } 00504 if (!empty($node->title)) { 00505 $node->decoration->attributes['title'] = $node->title; 00506 $node->decoration->attributedelimiters['title'] = '"'; 00507 } 00508 $node = $this->prepare_node($node); 00509 return $node; 00510 } 00515 protected function prepare_macro_node($node) 00516 { 00517 $node->output = ''; 00518 $this->call_macro($node); 00519 if (empty($node->output) and ($node->caption)) { 00520 $node->output = $node->caption; 00521 } 00522 return $node; 00523 } 00531 protected function prepare_node($node) 00532 { 00533 # trigger callouts 00534 $node = $this->call_classes($node); 00535 $node = $this->call_properties($node); 00536 # convert input decoration attributes, values, and properties into html attributes 00537 $attributes = array(); 00538 // attributes 00539 $attr = !empty($node->decoration->attributes)?$node->decoration->attributes:array(); 00540 $attrdelimiters = !empty($node->decoration->attributedelimiters)?$node->decoration->attributedelimiters:array(); 00541 foreach ($attr as $key => $value) { 00542 $attributes[] = $key . '=' . $attrdelimiters[$key] . $value . $attrdelimiters[$key]; 00543 } 00544 // classes 00545 $values = array(); 00546 $values = !empty($node->decoration->classes)?$node->decoration->classes:array(); 00547 $classes = preg_replace('/"/','\\"',implode(' ',$values)); // escape embedded double quotes 00548 if (!empty($classes)) $attributes[]='class="' . $classes . '"'; 00549 // styles 00550 $properties = array(); 00551 $properties = !empty($node->decoration->properties)?$node->decoration->properties:array(); 00552 $styles = array(); 00553 foreach ($properties as $key => $value) { 00554 $styles[] = $key . ':' . $value; 00555 } 00556 if (!empty($styles)) { 00557 $style = implode(';',preg_replace('/"/','\\"',$styles)); // escape embedded double quotes 00558 $attributes[] = 'style="' . $style . '"'; 00559 } 00560 if (!empty($attributes)) $node->opentag_head .= ' '; 00561 $node->attributes = $attributes; 00562 return $node; 00563 } 00570 protected function standard_assembly($node) 00571 { 00572 return $node->opentag_head . implode(' ',$node->attributes) . $node->opentag_tail 00573 . $node->elementcontent . $node->closetag; 00574 } 00578 protected function char_filter($text, $node = NULL) 00579 { 00580 if (isset($this->_charfilter_handler)) { 00581 return call_user_func($this->_charfilter_handler,$text,$node); 00582 } else { 00583 return htmlspecialchars($text); 00584 } 00585 } 00587 #------------------------------------------------------------------------------# 00588 #-----------------------------[ node emitters ]--------------------------------# 00589 #------------------------------------------------------------------------------# 00590 #==============================[ document ]====================================# 00591 00596 protected function _document_emit($node) 00597 { 00598 // anticipate event calls 00599 $node->opentag_head = ''; 00600 $node->closetag = ''; 00601 $node = $this->call_event('onemit',$node); 00602 $node->elementcontent = $this->emit_children($node); 00603 $node = $this->call_event('onafteremit',$node); 00604 return $node->opentag_head . $node->elementcontent . $node->closetag; 00605 } 00606 #=========================[ basic processing ]=================================# 00607 00611 protected function _paragraph_emit($node) // b decorator "p" 00612 { 00613 $node->opentag_head = "\n<p"; 00614 $node->opentag_tail = ">"; 00615 $node->elementcontent = $this->emit_children($node); 00616 $node->closetag = "</p>"; 00617 $node = $this->prepare_node($node); 00618 return $this->standard_assembly($node); 00619 } 00624 protected function _text_emit($node) 00625 { 00626 return $this->char_filter($node->textcontent,$node); 00627 } 00628 #================================[ core markup ]===============================# 00629 #--------------------------------[ basic markup ]------------------------------# 00630 00634 protected function _heading_emit($node) // b decorator "h" 00635 { 00636 $node->opentag_head = "\n<h" . $node->level; 00637 $node->opentag_tail = ">"; 00638 $node->elementcontent = $this->emit_children($node); 00639 $node->closetag = "</h". $node->level . ">"; 00640 $node = $this->prepare_node($node); 00641 return $this->standard_assembly($node); 00642 } 00647 protected function _emphasis_emit($node) 00648 { 00649 return "<em>" . $this->emit_children($node) . "</em>"; 00650 } 00655 protected function _strong_emit($node) 00656 { 00657 return "<strong>" . $this->emit_children($node) . "</strong>"; 00658 } 00663 protected function _linebreak_emit($node) 00664 { 00665 return "<br />\n"; 00666 } 00671 protected function _horizontalrule_emit($node) 00672 { 00673 return "\n<hr />"; 00674 } 00675 #--------------------------------[ links ]-------------------------------------# 00676 00680 protected function _link_emit($node) // i decorator "a" 00681 { 00682 $node->caption = $this->emit_children($node); 00683 // also available: $node->title 00684 $address = $node->target; 00685 $matches = array(); 00686 if (preg_match($this->_link_re,$address,$matches)) 00687 { 00688 isset($matches['anchor']) or ($matches['anchor'] = ''); 00689 isset($matches['internal_address']) or ($matches['internal_address'] = ''); 00690 isset($matches['symlink']) or ($matches['symlink'] = ''); 00691 isset($matches['internal_selector']) or ($matches['internal_selector'] = ''); 00692 isset($matches['internal_version']) or ($matches['internal_version'] = ''); 00693 isset($matches['external_address']) or ($matches['external_address'] = ''); 00694 isset($matches['external_proto']) or ($matches['external_proto'] = ''); 00695 isset($matches['external_selector']) or ($matches['external_selector'] = ''); 00696 isset($matches['external_mailaddress']) or ($matches['external_mailaddress'] = ''); 00697 isset($matches['external_mailproto']) or ($matches['external_mailproto'] = ''); 00698 isset($matches['external_mailselector']) or ($matches['external_mailselector'] = ''); 00699 isset($matches['rawlink']) or ($matches['rawlink'] = ''); 00700 00701 $node->linkparts = new StdClass(); 00702 $node->linkparts->anchor = $matches['anchor']; 00703 00704 $node->linkparts->internaladdress = $matches['internal_address']; 00705 $node->linkparts->symlink = $matches['symlink']; 00706 $node->linkparts->internalselector = $matches['internal_selector']; 00707 $node->linkparts->internalversion = $matches['internal_version']; 00708 00709 $node->linkparts->externaladdress = $matches['external_address']; 00710 $node->linkparts->externalprotocol = $matches['external_proto']; 00711 $node->linkparts->externalselector = $matches['external_selector']; 00712 00713 if ($matches['external_mailaddress']) { 00714 $node->linkparts->externaladdress = $matches['external_mailaddress']; 00715 $node->linkparts->externalprotocol = $matches['external_mailproto']; 00716 $node->linkparts->externalselector = $matches['external_mailselector']; 00717 } 00718 00719 $node->linkparts->rawlink = $matches['rawlink']; 00720 } 00721 if (empty($node->caption) and empty($node->linkparts->anchor)) 00722 $node->caption = $node->target; 00723 00724 $node->opentag_head = "<a"; 00725 $node->opentag_tail = ">"; 00726 $node->elementcontent = $node->caption; 00727 $node->closetag = "</a>"; 00728 $node->unknown = FALSE; 00729 $node = $this->prepare_link_node($node); // might set $node->unknown = TRUE; 00730 if ($node->unknown) { 00731 $node->opentag_head .= 'rel="nofollow" '; 00732 $node->opentag_tail .= '<span style="border-bottom:1px dashed gray">'; 00733 $node->closetag = '</span><sup>?</sup>' . $node->closetag; 00734 } 00735 return $this->standard_assembly($node); 00736 } 00737 #--------------------------------[ images ]------------------------------------# 00738 00742 protected function _image_emit($node) // i decorator "i" 00743 { 00744 $node->caption = $this->emit_children($node); 00745 // also available: $node->title 00746 $address = $node->target; 00747 $matches = array(); 00748 if (preg_match($this->_image_re,$address,$matches)) 00749 { 00750 isset($matches['internal_address']) or ($matches['internal_address'] = ''); 00751 isset($matches['symlink']) or ($matches['symlink'] = ''); 00752 isset($matches['internal_selector']) or ($matches['internal_selector'] = ''); 00753 isset($matches['internal_version']) or ($matches['internal_version'] = ''); 00754 isset($matches['external_address']) or ($matches['external_address'] = ''); 00755 isset($matches['external_proto']) or ($matches['external_proto'] = ''); 00756 isset($matches['external_selector']) or ($matches['external_selector'] = ''); 00757 isset($matches['rawlink']) or ($matches['rawlink'] = ''); 00758 00759 $node->linkparts = new StdClass(); 00760 $node->linkparts->internaladdress = $matches['internal_address']; 00761 $node->linkparts->symlink = $matches['symlink']; 00762 $node->linkparts->internalselector = $matches['internal_selector']; 00763 $node->linkparts->internalversion = $matches['internal_version']; 00764 00765 $node->linkparts->externaladdress = $matches['external_address']; 00766 $node->linkparts->externalprotocol = $matches['external_proto']; 00767 $node->linkparts->externalselector = $matches['external_selector']; 00768 00769 $node->linkparts->rawlink = $matches['rawlink']; 00770 } 00771 $node->opentag_head = "<img"; 00772 $node->opentag_tail = "/>"; 00773 $node = $this->prepare_image_node($node); 00774 return $node->opentag_head . implode(' ',$node->attributes) . $node->opentag_tail; 00775 } 00776 #--------------------------------[ lists ]-------------------------------------# 00777 00781 protected function _def_list_emit($node) // b decorator "dl" 00782 { 00783 $node->opentag_head = "\n<dl"; 00784 $node->opentag_tail = ">"; 00785 $node->elementcontent = $this->emit_children($node); 00786 $node->closetag = "\n</dl>"; 00787 $node = $this->prepare_node($node); 00788 return $this->standard_assembly($node); 00789 } 00794 protected function _def_term_emit($node) // decorator "dt" 00795 { 00796 $node->opentag_head = "\n<dt"; 00797 $node->opentag_tail = ">"; 00798 $node->elementcontent = $this->emit_children($node); 00799 $node->closetag = "</dt>"; 00800 $node = $this->prepare_node($node); 00801 return $this->standard_assembly($node); 00802 } 00807 protected function _def_desc_emit($node) // decorator "dd" 00808 { 00809 $node->opentag_head = "\n<dd"; 00810 $node->opentag_tail = ">"; 00811 $node->elementcontent = $this->emit_children($node); 00812 $node->closetag = "</dd>"; 00813 $node = $this->prepare_node($node); 00814 return $this->standard_assembly($node); 00815 } 00820 protected function _ordered_list_emit($node) // b decorator "ol" 00821 { 00822 $node->opentag_head = "\n<ol"; 00823 $node->opentag_tail = ">"; 00824 $node->elementcontent = $this->emit_children($node); 00825 $node->closetag = "\n</ol>"; 00826 $node = $this->prepare_node($node); 00827 return $this->standard_assembly($node); 00828 // return $node->opentag_head . implode(' ',$node->attributes) . $node->opentag_tail 00829 // . $node->elementcontent . $node->closetag; 00830 } 00835 protected function _unordered_list_emit($node) // b decorator "ul" 00836 { 00837 $node->opentag_head = "\n<ul"; 00838 $node->opentag_tail = ">"; 00839 $node->elementcontent = $this->emit_children($node); 00840 $node->closetag = "\n</ul>"; 00841 $node = $this->prepare_node($node); 00842 return $this->standard_assembly($node); 00843 } 00848 protected function _list_item_emit($node) // decorator "li" 00849 { 00850 $node->opentag_head = "\n<li"; 00851 $node->opentag_tail = ">"; 00852 $node->elementcontent = $this->emit_children($node); 00853 $node->closetag = "</li>"; 00854 $node = $this->prepare_node($node); 00855 return $this->standard_assembly($node); 00856 } 00857 #--------------------------------[ tables ]------------------------------------# 00858 00862 protected function _table_emit($node) // b decorator "table" 00863 { 00864 $node->opentag_head = "\n<table"; 00865 $node->opentag_tail = ">"; 00866 $node->elementcontent = $this->emit_children($node); 00867 $node->closetag = "\n</table>"; 00868 $node = $this->prepare_node($node); 00869 return $this->standard_assembly($node); 00870 } 00875 protected function _table_row_emit($node) // b decorator "tr" 00876 { 00877 $node->opentag_head = "\n<tr"; 00878 $node->opentag_tail = ">"; 00879 $node->elementcontent = $this->emit_children($node); 00880 $node->closetag = "\n</tr>"; 00881 $node = $this->prepare_node($node); 00882 return $this->standard_assembly($node); 00883 } 00888 protected function _table_headcell_emit($node) // b decorator "th" 00889 { 00890 $node->opentag_head = "\n<th"; 00891 $node->opentag_tail = ">\n"; 00892 $node->elementcontent = $this->emit_children($node); 00893 $node->closetag = "</th>"; 00894 $node = $this->prepare_node($node); 00895 return $this->standard_assembly($node); 00896 } 00901 protected function _table_cell_emit($node) // b decorator "td" 00902 { 00903 $node->opentag_head = "\n<td"; 00904 $node->opentag_tail = ">\n"; 00905 $node->elementcontent = $this->emit_children($node); 00906 $node->closetag = "</td>"; 00907 $node = $this->prepare_node($node); 00908 return $this->standard_assembly($node); 00909 } 00910 #=========================[ special decorators ]===============================# 00911 #---------------------------[ span decoration ]--------------------------------# 00912 00916 protected function _span_emit($node) // i decorator "s" 00917 { 00918 $node->opentag_head = "<span"; 00919 $node->opentag_tail = ">"; 00920 $node->elementcontent = $this->emit_children($node); 00921 $node->closetag = "</span>"; 00922 $node = $node = $this->prepare_node($node); 00923 return $this->standard_assembly($node); 00924 } 00925 #----------------------------[ block dividers ]--------------------------------# 00926 00930 protected function _blockdivider_emit($node) // b decorator "b" 00931 { 00932 $node->opentag_head = "\n<div"; 00933 $node->opentag_tail = ">"; 00934 $node->elementcontent = ''; 00935 $node->closetag = "\n</div>"; 00936 $node = $this->prepare_node($node); 00937 return $this->standard_assembly($node); 00938 } 00939 #============================[ preformatted text ]=============================# 00940 00944 protected function _code_emit($node) // i decorator "c" 00945 { 00946 $node->opentag_head = "<code"; 00947 $node->opentag_tail = ">"; 00948 $node->elementcontent = $node->textcontent; 00949 $node->escapecontent = TRUE; 00950 $node->closetag = "</code>"; 00951 $node = $this->prepare_node($node); 00952 if ($node->escapecontent) $node->elementcontent = $this->char_filter($node->elementcontent,$node); 00953 return $this->standard_assembly($node); 00954 } 00959 protected function _preformatted_emit($node) // b decorator "pre" 00960 { 00961 $node->opentag_head = "\n<pre"; 00962 $node->opentag_tail = ">\n"; 00963 $node->elementcontent = $node->textcontent; 00964 $node->escapecontent = TRUE; 00965 $node->closetag = "</pre>"; 00966 $node = $this->prepare_node($node); 00967 if ($node->escapecontent) $node->elementcontent = $this->char_filter($node->elementcontent,$node); 00968 return $this->standard_assembly($node); 00969 } 00970 #==============================[ advanced markup ]=============================# 00971 #------------------------------[ block declarations ]----------------------------# 00972 00976 protected function _blockdef_emit($node) // declaration decorator (various) 00977 { 00978 $blocktag = $node->blocktag; 00979 $node->knowntag = in_array($blocktag,$this->_blocktags); 00980 if (!$node->knowntag) 00981 { 00982 $node->opentag_head = "\n(:$blocktag " . $node->decoration->markup; 00983 $node->opentag_tail = ":)"; 00984 $node->closetag = "\n(:{$blocktag}end:)"; 00985 } 00986 elseif (substr($blocktag,0,2) == 'dl') 00987 { 00988 $dlmltag = substr($blocktag,2); 00989 $node->opentag_head = "\n<dl:" . $dlmltag; 00990 $node->opentag_tail = ">"; 00991 $node->closetag = "\n</dl:" . $dlmltag. '>'; 00992 } 00993 else 00994 { 00995 $node->opentag_head = "\n<$blocktag"; 00996 $node->opentag_tail = ">"; 00997 $node->closetag = "\n</$blocktag>"; 00998 } 00999 $node->elementcontent = ''; 01000 if (isset($this->_blockdef_handler)) 01001 $node = call_user_func($this->_blockdef_handler,$node); 01002 if (!$node->elementcontent) $node->elementcontent = $this->emit_children($node); 01003 if ($node->knowntag) 01004 { 01005 $node = $this->prepare_node($node); 01006 return $this->standard_assembly($node); 01007 } 01008 else 01009 { 01010 return $node->opentag_head . $node->opentag_tail 01011 . $node->elementcontent . $node->closetag; 01012 } 01013 } 01014 #--------------------------------[ macros ]--------------------------------# 01015 01019 protected function _macro_emit($node) // macro decorator 01020 { 01021 $node->caption = $this->emit_children($node); 01022 $node->processed = FALSE; // set to TRUE by prepare_macro_node if macro found. 01023 $node = $this->prepare_macro_node($node); 01024 if ($node->processed) 01025 { 01026 return $node->output; 01027 } else { // return re-assembled source markup 01028 $opentag_head = '<<' . $node->macroname; 01029 $arguments = property_exists($node,"decoration")? $node->decoration->markup: ''; 01030 if ($arguments != '') $arguments = ' ' . $arguments; 01031 $caption = $node->caption; 01032 if ($caption) 01033 $caption = '|' . $caption; 01034 $closetag = '>>'; 01035 return $this->char_filter($opentag_head . $arguments . $caption . $closetag,$node); 01036 } 01037 } 01039 }