Source define ('DOKU_LF',"\n"); } if ( !defined('DOKU_TAB') ) { // Some whitespace to help View > Source define ('DOKU_TAB',"\t"); } require_once DOKU_INC . 'inc/parser/renderer.php'; /** * @TODO Probably useful for have constant for linefeed formatting */ class Doku_Renderer_XHTML extends Doku_Renderer { var $doc = ''; var $headers = array(); var $footnotes = array(); var $footnoteIdStack = array(); var $acronyms = array(); var $smileys = array(); var $badwords = array(); var $entities = array(); var $interwiki = array(); var $lastsec = 0; function document_start() { ob_start(); } function document_end() { // add button for last section if any if($this->lastsec) $this->__secedit($this->lastsec,''); if ( count ($this->footnotes) > 0 ) { echo '
'.DOKU_LF; foreach ( $this->footnotes as $footnote ) { echo $footnote; } echo '
'.DOKU_LF; } $this->doc .= ob_get_contents(); ob_end_clean(); } function toc_open() { echo '
'.DOKU_LF; echo '
Table of Contents
'.DOKU_LF; echo '
'.DOKU_LF; } function tocbranch_open($level) { echo ''.DOKU_LF; } function toc_close() { echo '
'.DOKU_LF.'
'.DOKU_LF; } function header($text, $level, $pos) { global $conf; //handle section editing if($level <= $conf['maxseclevel']){ // add button for last section if any if($this->lastsec) $this->__secedit($this->lastsec,$pos-1); // remember current position $this->lastsec = $pos; } echo DOKU_LF.''; echo $this->__xmlEntities($text); echo "".DOKU_LF; } function section_open($level) { echo "
".DOKU_LF; } function section_close() { echo DOKU_LF.'
'.DOKU_LF; } function cdata($text) { echo $this->__xmlEntities($text); } function p_open() { echo DOKU_LF.'

'.DOKU_LF; } function p_close() { echo DOKU_LF.'

'.DOKU_LF; } function linebreak() { echo '
'.DOKU_LF; } function hr() { echo '
'.DOKU_LF; } function strong_open() { echo ''; } function strong_close() { echo ''; } function emphasis_open() { echo ''; } function emphasis_close() { echo ''; } function underline_open() { echo ''; } function underline_close() { echo ''; } function monospace_open() { echo ''; } function monospace_close() { echo ''; } function subscript_open() { echo ''; } function subscript_close() { echo ''; } function superscript_open() { echo ''; } function superscript_close() { echo ''; } function deleted_open() { echo ''; } function deleted_close() { echo ''; } function footnote_open() { $id = $this->__newFootnoteId(); echo ''.$id.')'; $this->footnoteIdStack[] = $id; ob_start(); } function footnote_close() { $contents = ob_get_contents(); ob_end_clean(); $id = array_pop($this->footnoteIdStack); $contents = '
'. $id.') ' .DOKU_LF .$contents. "\n" . '
' . DOKU_LF; $this->footnotes[$id] = $contents; } function listu_open() { echo ''.DOKU_LF; } function listo_open() { echo '
    '.DOKU_LF; } function listo_close() { echo '
'.DOKU_LF; } function listitem_open($level) { echo '
  • '; } function listitem_close() { echo '
  • '.DOKU_LF; } function listcontent_open() { echo ''; } function listcontent_close() { echo ''.DOKU_LF; } function unformatted($text) { echo $this->__xmlEntities($text); } /** */ function php($text) { global $conf; if($conf['phpok']){ eval($text); }else{ $this->file($text); } } /** */ function html($text) { global $conf; if($conf['htmlok']){ echo $text; }else{ $this->file($text); } } function preformatted($text) { echo '
    ' . $this->__xmlEntities($text) . '
    '. DOKU_LF; } function file($text) { echo '
    ' . $this->__xmlEntities($text). '
    '. DOKU_LF; } /** * @TODO Shouldn't this output '.DOKU_LF; } /** * @TODO Shouldn't this output ? */ function quote_close() { echo ''.DOKU_LF; } /** */ function code($text, $language = NULL) { global $conf; if ( is_null($language) ) { $this->preformatted($text); } else { // Handle with Geshi here FIXME: strip first beginning newline require_once(DOKU_INC . 'inc/geshi.php'); $geshi = new GeSHi($text, strtolower($language), DOKU_INC . 'inc/geshi'); $geshi->enable_classes(); $geshi->set_header_type(GESHI_HEADER_PRE); $geshi->set_overall_class('code'); $geshi->set_link_target($conf['target']['extern']); $text = $geshi->parse_code(); echo $text; } } function acronym($acronym) { if ( array_key_exists($acronym, $this->acronyms) ) { $title = $this->__xmlEntities($this->acronyms[$acronym]); echo ''.$this->__xmlEntities($acronym).''; } else { echo $this->__xmlEntities($acronym); } } /** */ function smiley($smiley) { if ( array_key_exists($smiley, $this->smileys) ) { $title = $this->__xmlEntities($this->smileys[$smiley]); echo ''.
                    $this->__xmlEntities($smiley).''; } else { echo $this->__xmlEntities($smiley); } } /** * not used function wordblock($word) { if ( array_key_exists($word, $this->badwords) ) { echo '** BLEEP **'; } else { echo $this->__xmlEntities($word); } } */ function entity($entity) { if ( array_key_exists($entity, $this->entities) ) { echo $this->entities[$entity]; } else { echo $this->__xmlEntities($entity); } } function multiplyentity($x, $y) { echo "$x×$y"; } function singlequoteopening() { echo "‘"; } function singlequoteclosing() { echo "’"; } function doublequoteopening() { echo "“"; } function doublequoteclosing() { echo "”"; } /** */ function camelcaselink($link) { $this->internallink($link,$link); } /** * @TODO Support media * @TODO correct attributes */ function internallink($id, $name = NULL) { global $conf; $name = $this->__getLinkTitle($name, $this->__simpleTitle($id), $isImage); resolve_pageid($id,$exists); if ( !$isImage ) { if ( $exists ) { $class='wikilink1'; } else { $class='wikilink2'; } } else { $class='media'; } //prepare for formating $link['target'] = $conf['target']['wiki']; $link['style'] = ''; $link['pre'] = ''; $link['suf'] = ''; $link['more'] = 'onclick="return svchk()" onkeypress="return svchk()"'; $link['class'] = $class; $link['url'] = wl($id); $link['name'] = $name; $link['title'] = $id; //output formatted echo $this->__formatLink($link); } /** * @TODO Should list assume blacklist check already made? * @TODO External link icon * @TODO correct attributes */ function externallink($link, $title = NULL) { echo '__getLinkTitle($title, $link, $isImage); if ( !$isImage ) { echo ' class="urlextern"'; } else { echo ' class="media"'; } echo ' target="_blank" href="'.$this->__xmlEntities($link).'"'; echo ' onclick="return svchk()" onkeypress="return svchk()">'; echo $title; echo ''; } /** * @TODO Remove hard coded link to splitbrain.org on style */ function interwikilink($link, $title = NULL, $wikiName, $wikiUri) { // RESOLVE THE URL if ( isset($this->interwiki[$wikiName]) ) { $wikiUriEnc = urlencode($wikiUri); if ( strstr($this->interwiki[$wikiName],'{URL}' ) !== FALSE ) { $url = str_replace('{URL}', $wikiUriEnc, $this->interwiki[$wikiName] ); } else if ( strstr($this->interwiki[$wikiName],'{NAME}' ) !== FALSE ) { $url = str_replace('{NAME}', $wikiUriEnc, $this->interwiki[$wikiName] ); } else { $url = $this->interwiki[$wikiName] . urlencode($wikiUri); } } else { // Default to Google I'm feeling lucky $url = 'http://www.google.com/search?q='.urlencode($wikiUri).'&btnI=lucky'; } // BUILD THE LINK echo '__getLinkTitle($title, $wikiUri, $isImage); if ( !$isImage ) { echo ' class="interwiki"'; } else { echo ' class="media"'; } echo ' href="'.$this->__xmlEntities($url).'"'; if ( FALSE !== ( $type = interwikiImgExists($wikiName) ) ) { echo ' style="background: transparent url(http://wiki.splitbrain.org/interwiki/'. $wikiName.'.'.$type.') 0px 1px no-repeat;"'; } echo ' onclick="return svchk()" onkeypress="return svchk()">'; echo $title; echo ''; } /** * @TODO Correct the CSS class for files? (not windows) * @TODO Remove hard coded URL to splitbrain.org */ function filelink($link, $title = NULL) { echo '__getLinkTitle($title, $link, $isImage); if ( !$isImage ) { echo ' class="windows"'; } else { echo ' class="media"'; } echo ' href="'.$this->__xmlEntities($link).'"'; echo ' style="background: transparent url(http://wiki.splitbrain.org/images/windows.gif) 0px 1px no-repeat;"'; echo ' onclick="return svchk()" onkeypress="return svchk()">'; echo $title; echo ''; } /** * @TODO Remove hard coded URL to splitbrain.org * @TODO Add error message for non-IE users */ function windowssharelink($link, $title = NULL) { echo '__getLinkTitle($title, $link, $isImage); if ( !$isImage ) { echo ' class="windows"'; } else { echo ' class="media"'; } $link = str_replace('\\','/',$link); $link = 'file:///'.$link; echo ' href="'.$this->__xmlEntities($link).'"'; echo ' style="background: transparent url(http://wiki.splitbrain.org/images/windows.gif) 0px 1px no-repeat;"'; echo ' onclick="return svchk()" onkeypress="return svchk()">'; echo $title; echo ''; } /** * @TODO Protect email address from harvesters * @TODO Remove hard coded link to splitbrain.org */ function email($address, $title = NULL) { echo '__getLinkTitle($title, $address, $isImage); if ( !$isImage ) { echo ' class="mail"'; } else { echo ' class="media"'; } echo ' href="mailto:'.$this->__xmlEntities($address).'"'; echo ' style="background: transparent url(http://wiki.splitbrain.org/images/mail_icon.gif) 0px 1px no-repeat;"'; echo ' onclick="return svchk()" onkeypress="return svchk()">'; echo $title; echo ''; } /** * @TODO Resolve namespaces * @TODO Add image caching * @TODO Remove hard coded link to splitbrain.org */ function internalmedia ( $src,$title=NULL,$align=NULL,$width=NULL,$height=NULL,$cache=NULL ) { // Sort out the namespace here... if ( strpos($src,':') ) { $src = explode(':',$src); $src = $src[1]; } echo ''; } /** * @TODO Add image caching */ function externalmedia ( $src,$title=NULL,$align=NULL,$width=NULL,$height=NULL,$cache=NULL ) { echo ''; } // $numrows not yet implemented function table_open($maxcols = NULL, $numrows = NULL){ echo ''.DOKU_LF; } function table_close(){ echo '
    '.DOKU_LF.'
    '.DOKU_LF; } function tablerow_open(){ echo DOKU_TAB . '' . DOKU_LF . DOKU_TAB . DOKU_TAB; } function tablerow_close(){ echo DOKU_LF . DOKU_TAB . '' . DOKU_LF; } function tableheader_open($colspan = 1, $align = NULL){ echo ' 1 ) { echo ' colspan="'.$colspan.'"'; } echo '>'; } function tableheader_close(){ echo ''; } function tablecell_open($colspan = 1, $align = NULL){ echo ' 1 ) { echo ' colspan="'.$colspan.'"'; } echo '>'; } function tablecell_close(){ echo ''; } //---------------------------------------------------------- // Utils /** * Assembles all parts defined by the link formater below * Returns HTML for the link * * @author Andreas Gohr */ function __formatLink($link){ //make sure the url is XHTML compliant (skip mailto) if(substr($link['url'],0,7) != 'mailto:'){ $link['url'] = str_replace('&','&',$link['url']); $link['url'] = str_replace('&amp;','&',$link['url']); } //remove double encodings in titles $link['title'] = str_replace('&amp;','&',$link['title']); $ret = ''; $ret .= $link['pre']; $ret .= ' */ function __simpleTitle($name){ global $conf; if($conf['useslash']){ $nssep = '[:;/]'; }else{ $nssep = '[:;]'; } return preg_replace('!.*'.$nssep.'!','',$name); } function __newFootnoteId() { static $id = 1; return $id++; } function __xmlEntities($string) { return htmlspecialchars($string); } /** * @TODO Tuning needed - e.g. utf8 strtolower ? */ function __headerToLink($title) { return preg_replace('/\W/','_',trim($title)); } /** * Adds code for section editing button */ function __secedit($f, $t){ print ''; } function __getLinkTitle($title, $default, & $isImage) { $isImage = FALSE; if ( is_null($title) ) { return $this->__xmlEntities($default); } else if ( is_string($title) ) { return $this->__xmlEntities($title); } else if ( is_array($title) ) { $isImage = TRUE; return $this->__imageTitle($title); } } /** * @TODO Resolve namespace on internal images * @TODO Remove hard coded url to splitbrain.org * @TODO Image caching */ function __imageTitle($img) { if ( $img['type'] == 'internalmedia' ) { // Resolve here... if ( strpos($img['src'],':') ) { $src = explode(':',$img['src']); $src = $src[1]; } else { $src = $img['src']; } $imgStr = '__xmlEntities($img['src']).'"'; } if ( !is_null($img['title']) ) { $imgStr .= ' alt="'.$this->__xmlEntities($img['title']).'"'; } else { $imgStr .= ' alt=""'; } if ( !is_null($img['align']) ) { $imgStr .= ' align="'.$img['align'].'"'; } if ( !is_null($img['width']) ) { $imgStr .= ' width="'.$this->__xmlEntities($img['width']).'"'; } if ( !is_null($img['height']) ) { $imgStr .= ' height="'.$this->__xmlEntities($img['height']).'"'; } $imgStr .= '/>'; return $imgStr; } } /** * Test whether there's an image to display with this interwiki link */ function interwikiImgExists($name) { static $exists = array(); if ( array_key_exists($name,$exists) ) { return $exists[$name]; } if( @file_exists( DOKU. 'interwiki/'.$name.'.png') ) { $exists[$name] = 'png'; } else if ( @file_exists( DOKU . 'interwiki/'.$name.'.gif') ) { $exists[$name] = 'gif'; } else { $exists[$name] = FALSE; } return $exists[$name]; } /** * For determining whether to use CSS class "wikilink1" or "wikilink2" * @todo use configinstead of DOKU_DATA * @deprecated -> resolve_pagename should be used */ function wikiPageExists($name) { msg("deprecated wikiPageExists called",-1); static $pages = array(); if ( array_key_exists($name,$pages) ) { return $pages[$name]; } $file = str_replace(':','/',$name).'.txt'; if ( @file_exists( DOKU_DATA . $file ) ) { $pages[$name] = TRUE; } else { $pages[$name] = FALSE; } return $pages[$name]; }