'.DOKU_LF;
}
function linebreak() {
$this->doc .= '
';
}
function strong_open() {
$this->doc .= '
';
}
function strong_close() {
$this->doc .= '';
}
function emphasis_open() {
$this->doc .= '
';
}
function emphasis_close() {
$this->doc .= '';
}
function underline_open() {
$this->doc .= '
';
}
function underline_close() {
$this->doc .= '';
}
function monospace_open() {
$this->doc .= '
';
}
function monospace_close() {
$this->doc .= '';
}
function subscript_open() {
$this->doc .= '
';
}
function subscript_close() {
$this->doc .= '';
}
function superscript_open() {
$this->doc .= '
';
}
function superscript_close() {
$this->doc .= '';
}
function deleted_open() {
$this->doc .= '
';
}
function deleted_close() {
$this->doc .= '';
}
/*
* Tables
*/
function table_open($maxcols = NULL, $numrows = NULL){
$this->doc .= '
';
for($i=0; $i<$maxcols; $i++){
$this->doc .= '';
}
}
function table_close(){
$this->doc .= '';
}
function tablerow_open(){
$this->doc .= '
';
}
function tablerow_close(){
$this->doc .= '';
}
function tableheader_open($colspan = 1, $align = "left"){
$this->doc .= '
doc .= ' table:style-name="tablealign'.$align.'"';
if ( $colspan > 1 ) {
$this->doc .= ' table:number-columns-spanned="'.$colspan.'"';
}
$this->doc .= '>';
$this->p_open('Table_20_Heading');
}
function tableheader_close(){
$this->p_close();
$this->doc .= '';
}
function tablecell_open($colspan = 1, $align = "left"){
$this->doc .= '
1 ) {
$this->doc .= ' table:number-columns-spanned="'.$colspan.'"';
}
$this->doc .= '>';
if (!$align) $align = "left";
$style = "tablealign".$align;
$this->p_open($style);
}
function tablecell_close(){
$this->p_close();
$this->doc .= '';
}
/**
* Callback for footnote start syntax
*
* All following content will go to the footnote instead of
* the document. To achieve this the previous rendered content
* is moved to $store and $doc is cleared
*
* @author Andreas Gohr
*/
function footnote_open() {
// move current content to store and record footnote
$this->store = $this->doc;
$this->doc = '';
}
/**
* Callback for footnote end syntax
*
* All rendered content is moved to the $footnotes array and the old
* content is restored from $store again
*
* @author Andreas Gohr
*/
function footnote_close() {
// recover footnote into the stack and restore old content
$footnote = $this->doc;
$this->doc = $this->store;
$this->store = '';
// check to see if this footnote has been seen before
$i = array_search($footnote, $this->footnotes);
if ($i === false) {
$i = count($this->footnotes);
// its a new footnote, add it to the $footnotes array
$this->footnotes[$i] = $footnote;
$this->doc .= '';
$this->doc .= ''.($i+1).'';
$this->doc .= '';
$this->doc .= '';
$this->doc .= $footnote;
$this->doc .= '';
$this->doc .= '';
$this->doc .= '';
} else {
// seen this one before - just reference it FIXME: style isn't correct yet
$this->doc .= ''.($i+1).'';
}
}
function listu_open() {
$this->p_close();
$this->doc .= '';
}
function listu_close() {
$this->doc .= '';
}
function listo_open() {
$this->p_close();
$this->doc .= '';
}
function listo_close() {
$this->doc .= '';
}
function listitem_open($level) {
$this->in_list_item = true;
$this->doc .= '';
}
function listitem_close() {
$this->in_list_item = false;
$this->doc .= '';
}
function listcontent_open() {
$this->doc .= '';
}
function listcontent_close() {
$this->doc .= '';
}
function unformatted($text) {
$this->doc .= $this->_xmlEntities($text);
}
function acronym($acronym) {
$this->doc .= $this->_xmlEntities($acronym);
}
function smiley($smiley) {
if ( array_key_exists($smiley, $this->smileys) ) {
$src = DOKU_INC."lib/images/smileys/".$this->smileys[$smiley];
$this->_odpAddImage($src);
} else {
$this->doc .= $this->_xmlEntities($smiley);
}
}
function entity($entity) {
# UTF-8 entity decoding is broken in PHP <5
if (version_compare(phpversion(), "5.0.0") and array_key_exists($entity, $this->entities) ) {
# decoding may fail for missing Multibyte-Support in entity_decode
$dec = @html_entity_decode($this->entities[$entity],ENT_NOQUOTES,'UTF-8');
if($dec){
$this->doc .= $this->_xmlEntities($dec);
}else{
$this->doc .= $this->_xmlEntities($entity);
}
} else {
$this->doc .= $this->_xmlEntities($entity);
}
}
function multiplyentity($x, $y) {
$this->doc .= $x.'×'.$y;
}
function singlequoteopening() {
global $lang;
$this->doc .= $lang['singlequoteopening'];
}
function singlequoteclosing() {
global $lang;
$this->doc .= $lang['singlequoteclosing'];
}
function apostrophe() {
global $lang;
$this->doc .= $lang['apostrophe'];
}
function doublequoteopening() {
global $lang;
$this->doc .= $lang['doublequoteopening'];
}
function doublequoteclosing() {
global $lang;
$this->doc .= $lang['doublequoteclosing'];
}
function php($text, $wrapper='dummy') {
$this->monospace_open();
$this->doc .= $this->_xmlEntities($text);
$this->monospace_close();
}
function phpblock($text) {
$this->file($text);
}
function html($text, $wrapper='dummy') {
$this->monospace_open();
$this->doc .= $this->_xmlEntities($text);
$this->monospace_close();
}
function htmlblock($text) {
$this->file($text);
}
/**
* static call back to replace spaces
*/
function _preserveSpace($matches){
$spaces = $matches[1];
$len = strlen($spaces);
return '';
}
function preformatted($text) {
$this->_preformatted($text);
}
function file($text, $language=null, $filename=null) {
$this->_highlight('file', $text, $language);
}
function quote_open() {
if (!$this->in_paragraph) { // only start a new par if we're not already in one
$this->p_open();
}
$this->doc .= ">";
}
function quote_close() {
if ($this->in_paragraph) { // only close the paragraph if we're actually in one
$this->p_close();
}
}
function code($text, $language=null, $filename=null) {
$this->_highlight('code', $text, $language);
}
function _preformatted($text, $style="Preformatted_20_Text", $notescaped=true) {
if ($notescaped) {
$text = $this->_xmlEntities($text);
}
if (strpos($text, "\n") !== FALSE and strpos($text, "\n") == 0) {
// text starts with a newline, remove it
$text = substr($text,1);
}
$text = str_replace("\n",'',$text);
$text = preg_replace_callback('/( +)/',array('renderer_plugin_odp','_preserveSpace'),$text);
if ($this->in_list_item) { // if we're in a list item, we must close the tag
$this->doc .= '';
$this->doc .= '';
$this->doc .= $text;
$this->doc .= '';
$this->doc .= '';
} else {
$this->doc .= '';
$this->doc .= $text;
$this->doc .= '';
}
}
function _highlight($type, $text, $language=null) {
global $conf;
$style_name = "Source_20_Code";
if ($type == "file") $style_name = "Source_20_File";
if (is_null($language)) {
$this->_preformatted($text, $style_name);
return;
}
// from inc/parserutils.php:p_xhtml_cached_geshi()
require_once(DOKU_INC . 'inc/geshi.php');
$geshi = new GeSHi($text, $language, DOKU_INC . 'inc/geshi');
$geshi->set_encoding('utf-8');
// $geshi->enable_classes(); DO NOT WANT !
$geshi->set_header_type(GESHI_HEADER_PRE);
$geshi->enable_keyword_links(false);
// remove GeSHi's wrapper element (we'll replace it with our own later)
// we need to use a GeSHi wrapper to avoid
throughout the highlighted text
$highlighted_code = trim(preg_replace('!^]*>|
$!','',$geshi->parse_code()),"\n\r");
// remove useless leading and trailing whitespace-newlines
$highlighted_code = preg_replace('/^ \n/','',$highlighted_code);
$highlighted_code = preg_replace('/\n $/','',$highlighted_code);
// replace styles
$highlighted_code = str_replace("", "", $highlighted_code);
$highlighted_code = preg_replace_callback('//', array('renderer_plugin_odp','_convert_css_styles'), $highlighted_code);
// cleanup leftover span tags
$highlighted_code = preg_replace('/]*>/', "", $highlighted_code);
$highlighted_code = str_replace(" ", " ", $highlighted_code);
$this->_preformatted($highlighted_code, $style_name, false);
}
function _convert_css_styles($matches) {
$all_css_styles = $matches[1];
// parse the CSS attribute
$css_styles = array();
foreach(explode(";", $all_css_styles) as $css_style) {
$css_style_array = explode(":", $css_style);
if (!trim($css_style_array[0]) or !trim($css_style_array[1])) {
continue;
}
$css_styles[trim($css_style_array[0])] = trim($css_style_array[1]);
}
// create the ODP xml style
$style_name = "highlight." . $this->highlight_style_num;
$this->highlight_style_num += 1;
$style_content = '
$style_value) {
// Hats off to those who thought out the OpenDocument spec: styling syntax is similar to CSS !
$style_content .= 'fo:'.$style_key.'="'.$style_value.'" ';
}
$style_content .= '/>
';
// add the style to the library
$this->autostyles[$style_name] = $style_content;
// now make use of the new style
return '';
}
function internalmedia ($src, $title=NULL, $align=NULL, $width=NULL,
$height=NULL, $cache=NULL, $linking=NULL) {
global $conf;
global $ID;
resolve_mediaid(getNS($ID),$src, $exists);
list($ext,$mime) = mimetype($src);
if(substr($mime,0,5) == 'image'){
$file = mediaFN($src);
$this->_odpAddImage($file, $width, $height, $align, $title);
}else{
// FIXME build absolute medialink and call externallink()
$this->code('FIXME internalmedia: '.$src);
}
}
function externalmedia ($src, $title=NULL, $align=NULL, $width=NULL,
$height=NULL, $cache=NULL, $linking=NULL) {
global $conf;
global $ID;
list($ext,$mime) = mimetype($src);
if(substr($mime,0,5) == 'image'){
if($width) {
$width = 'svg:width="'.(($width/96.0)*2.54).'cm"';
} else {
$width = 'svg:rel-width="100%"';
}
if($height) {
$height = 'svg:height="'.(($height/96.0)*2.54).'cm"';
} else {
$height = 'svg:rel-height="100%"';
}
$style = 'media'.$align;
if($align){
$anchor = 'paragraph';
}else{
$anchor = 'as-char';
}
$this->doc .= '';
$this->doc .= '';
$this->doc .= '';
}else{
$this->externallink($src,$title);
}
}
function camelcaselink($link) {
$this->internallink($link,$link);
}
function reference($id, $name = NULL) {
$this->doc .= 'doc .= '>'.$this->_xmlEntities($name).'';
} else {
$this->doc .= '/>';
}
}
/**
* Render an internal Wiki Link
*
* @author Andreas Gohr
*/
function internallink($id, $name = NULL) {
global $conf;
global $ID;
// default name is based on $id as given
$default = $this->_simpleTitle($id);
// now first resolve and clean up the $id
resolve_pageid(getNS($ID),$id,$exists);
$name = $this->_getLinkTitle($name, $default, $isImage, $id);
// build the absolute URL (keeping a hash if any)
list($id,$hash) = explode('#',$id,2);
$url = wl($id,'',true);
if($hash) $url .='#'.$hash;
if ($ID == $id) {
$this->reference($hash, $name);
} else {
$this->_doLink($url,$name);
}
}
/**
* Add external link
*/
function externallink($url, $name = NULL) {
global $conf;
$name = $this->_getLinkTitle($name, $url, $isImage);
$this->_doLink($url,$name);
}
/**
* Just print local links
*
* @fixme add image handling
*/
function locallink($hash, $name = NULL){
$name = $this->_getLinkTitle($name, $hash, $isImage);
$this->doc .= $name;
}
/**
* InterWiki links
*/
function interwikilink($match, $name = NULL, $wikiName, $wikiUri) {
$name = $this->_getLinkTitle($name, $wikiUri, $isImage);
$url = $this-> _resolveInterWiki($wikiName,$wikiUri);
$this->_doLink($url,$name);
}
/**
* Just print WindowsShare links
*
* @fixme add image handling
*/
function windowssharelink($url, $name = NULL) {
$name = $this->_getLinkTitle($name, $url, $isImage);
$this->doc .= $name;
}
/**
* Just print email links
*
* @fixme add image handling
*/
function emaillink($address, $name = NULL) {
$name = $this->_getLinkTitle($name, $address, $isImage);
$this->_doLink("mailto:".$address,$name);
}
/**
* Add a hyperlink, handling Images correctly
*
* @author Andreas Gohr
*/
function _doLink($url,$name){
$url = $this->_xmlEntities($url);
if(is_array($name)){
// Images
if($url) $this->doc .= '';
if($name['type'] == 'internalmedia'){
$this->internalmedia($name['src'],
$name['title'],
$name['align'],
$name['width'],
$name['height'],
$name['cache'],
$name['linking']);
}
if($url) $this->doc .= '';
}else{
// Text
if($url) $this->doc .= '';
$this->doc .= $name; // we get the name already XML encoded
if($url) $this->doc .= '';
}
}
/**
* Construct a title and handle images in titles
*
* @author Harry Fuecks
*/
function _getLinkTitle($title, $default, & $isImage, $id=null) {
global $conf;
$isImage = false;
if ( is_null($title) ) {
if ($conf['useheading'] && $id) {
$heading = p_get_first_heading($id);
if ($heading) {
return $this->_xmlEntities($heading);
}
}
return $this->_xmlEntities($default);
} else if ( is_string($title) ) {
return $this->_xmlEntities($title);
} else if ( is_array($title) ) {
$isImage = true;
return $title;
}
}
/**
* Creates a linkid from a headline
*
* @param string $title The headline title
* @param boolean $create Create a new unique ID?
* @author Andreas Gohr
*/
function _headerToLink($title,$create=false) {
$title = str_replace(':','',cleanID($title));
$title = ltrim($title,'0123456789._-');
if(empty($title)) $title='section';
if($create){
// make sure tiles are unique
$num = '';
while(in_array($title.$num,$this->headers)){
($num) ? $num++ : $num = 1;
}
$title = $title.$num;
$this->headers[] = $title;
}
return $title;
}
function _xmlEntities($value) {
return str_replace( array('&','"',"'",'<','>'), array('&','"',''','<','>'), $value);
}
function rss ($url,$params){
global $lang;
global $conf;
require_once(DOKU_INC.'inc/FeedParser.php');
$feed = new FeedParser();
$feed->feed_url($url);
//disable warning while fetching
if (!defined('DOKU_E_LEVEL')) { $elvl = error_reporting(E_ERROR); }
$rc = $feed->init();
if (!defined('DOKU_E_LEVEL')) { error_reporting($elvl); }
//decide on start and end
if($params['reverse']){
$mod = -1;
$start = $feed->get_item_quantity()-1;
$end = $start - ($params['max']);
$end = ($end < -1) ? -1 : $end;
}else{
$mod = 1;
$start = 0;
$end = $feed->get_item_quantity();
$end = ($end > $params['max']) ? $params['max'] : $end;;
}
$this->listu_open();
if($rc){
for ($x = $start; $x != $end; $x += $mod) {
$item = $feed->get_item($x);
$this->listitem_open(0);
$this->listcontent_open();
$this->externallink($item->get_permalink(),
$item->get_title());
if($params['author']){
$author = $item->get_author(0);
if($author){
$name = $author->get_name();
if(!$name) $name = $author->get_email();
if($name) $this->cdata(' '.$lang['by'].' '.$name);
}
}
if($params['date']){
$this->cdata(' ('.$item->get_date($conf['dformat']).')');
}
if($params['details']){
$this->cdata(strip_tags($item->get_description()));
}
$this->listcontent_close();
$this->listitem_close();
}
}else{
$this->listitem_open(0);
$this->listcontent_open();
$this->emphasis_open();
$this->cdata($lang['rssfailed']);
$this->emphasis_close();
$this->externallink($url);
$this->listcontent_close();
$this->listitem_close();
}
$this->listu_close();
}
function _odpAddImage($src, $width = NULL, $height = NULL, $align = NULL, $title = NULL, $style = NULL){
list($ext,$mime) = mimetype($src);
$name = 'Pictures/'.md5($src).'.'.$ext;
if(!$this->manifest[$name]){
$this->manifest[$name] = $mime;
$this->ZIP->add_File(io_readfile($src,false),$name,0);
}
// make sure width and height is available
// FIXME we don't have the dimension of an external file
// (except it's cached, but this is not the default) there seems
// to be no way to specify "use original image" in ODF - thus
// a hardcoded default size of 200 pixel here
if(!$width || !$height){
$info = getimagesize($src);
if(!$width){
$width = $info[0];
$height = $info[1];
}else{
$height = round(($width * $info[1]) / $info[0]);
}
}
// convert from pixel to centimeters
$width = (($width/96.0)*2.54);
$height = (($height/96.0)*2.54);
// Don't be wider than the page
if ($width >= 17){ // FIXME : this assumes A4 page format with 2cm margins
$width = $width.'cm" style:rel-width="100%';
$height = $height.'cm" style:rel-height="scale';
} else {
$width = $width.'cm';
$height = $height.'cm';
}
if($align){
$anchor = 'paragraph';
}else{
$anchor = 'as-char';
}
if (!$style or !array_key_exists($style, $this->autostyles)) {
$style = 'media'.$align;
}
if ($title) {
$this->doc .= '';
$this->doc .= '';
$this->doc .= '';
}
$this->doc .= '';
$this->doc .= '';
$this->doc .= '';
if ($title) {
$this->doc .= $this->_xmlEntities($title).'';
}
}
}
//Setup VIM: ex: et ts=4 enc=utf-8 :