*/ // must be run within Dokuwiki if (!defined('DOKU_INC')) die(); if (!defined('DOKU_LF')) define('DOKU_LF', "\n"); if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t"); require_once DOKU_INC . 'inc/parser/renderer.php'; require_once DOKU_INC . 'inc/html.php'; define('DEBUG', isset($_REQUEST['debug'])); function callback_marker($a) { // Wiki ID Wiki Intention Mellel Name Mellel Number $colorMap['ffff00'] = 1; // ffff00 Yellow Bible Banana 1 $colorMap['dda0dd'] = 2; // ff0000 Red Salmon 2 $colorMap['ffa500'] = 3; // ffa500 Orange Cantaloupe 3 $colorMap['008000'] = 4; // 008000 Green Rashi Lime 4 $colorMap['6495ed'] = 5; // 6495ed Blue Rashbam Sky 5 $colorMap['ff00ff'] = 6; // ff00ff Pink Rut Rabba Light Lavender 6 $colorMap['87ceeb'] = 7; // 87ceeb Gray Quara Magnesium 7 $colorMap['00ffff'] = 8; // 00ffff Black Other Sirection Midnight 8 $colorMap['ff0000'] = 2; $colorMap['008080'] = 4; if (isset($colorMap[$a[1]])) { $result = $colorMap[$a[1]]; } else { $result = 1; } return 'marker=\''.$result.'\''; } class renderer_plugin_mellelexport extends Doku_Renderer { public $info = array( 'cache' => false, // may the rendered result cached? 'toc' => false, // render the TOC? ); public $opened = 0; function getInfo() { return confToHash(dirname(__FILE__).'/plugin.info.txt'); } function getFormat() { return 'mellelexport'; } function isSingleton() { return false; } function __construct() { require_once dirname(__FILE__).'/mapping.php'; $this->conf['m'] = $m; } function document_start() { if (!defined('RECURSIVE_MELLEL')) { define('RECURSIVE_MELLEL', TRUE); if (!defined('DEBUG')) { define('DEBUG', TRUE); } set_time_limit(60*5); if (isset($_REQUEST['list'])) { $dirs = glob('/var/www/kolchose.org/inge/wiki/data/pages/*'); echo '

No files

'; foreach ($dirs as $dir) { if (is_file($dir)) { $new_dir = $dir; // $new_dir = str_replace('/var/www/kolchose.org/inge/wiki/data/pages/', '', $new_dir); // $new_dir = str_replace('.txt', '', $new_dir); $new_dirs[] = $new_dir; } else { echo $dir.'
'; } } unset($dirs); echo '

Formatation ok?

'; // $test_file = $new_dirs[1]; // // echo $test_file.'
'; #var_dump( #self::render(file_get_contents($test_file), 'mellelexport'); #); $i = 0; foreach($new_dirs as $file) { echo $file.'
'; self::render(file_get_contents($file), 'mellelexport'); ob_flush(); $i++; if ($i > 50) { exit; } } exit; } } plugin_disable('highlight'); if (in_array('highlight', plugin_list())) { die('ERROR: highlight loaded 1'); } global $ID; parent::document_start(); // If older or equal to 2007-06-26, we need to disable caching $dw_version = preg_replace('/[^\d]/', '', getversion()); if (version_compare($dw_version, "20070626", "<=")) { $this->info["cache"] = false; } $contentType = class_exists('ZipArchive') ? 'application/zip' : 'text/xml'; $contentFileName = class_exists('ZipArchive') ? noNS($ID).'.mellel' : 'main.xml'; // TODO configuration if (class_exists('ZipArchive') AND true) { $contentFileName = date('Y-m-d_').$contentFileName; } // send the content type header, new method after 2007-06-26 (handles caching) if (!DEBUG) { if (version_compare($dw_version, "20070626")) { // store the content type headers in metadata $headers = array( 'Content-Type' => $contentType, 'Content-Disposition' => 'attachment; filename="'.$contentFileName.'";', ); p_set_metadata($ID, array('format' => array('mellelexport' => $headers) )); } else { // older method header('Content-Type: '.$contentType); header('Content-Disposition: attachment; filename="'.$contentFileName.'";'); } } else { header('Content-Type: text/html; charset=utf-8'); echo ''; # echo ''; echo ''; } } function document_end() { if (in_array('highlight', plugin_list())) { die('ERROR: highlight loaded '.__FUNCTION__); } global $ID, $INFO; // Remove trailing empty pharentis, they can case crashes $this->doc = trim($this->doc); $pattern = '

'; while (substr($this->doc, 0, strlen($pattern)) == $pattern) { $this->doc = substr($this->doc, strlen($pattern)); } $pattern2 = '

'; while (substr($this->doc, 0, strlen($pattern2)) == $pattern2) { $this->doc = substr($this->doc, strlen($pattern2)); } // http://stackoverflow.com/a/14464026/22470 $this->doc = preg_replace('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $this->doc); // Global replacements // General replace for empty tags? // TODO They do now work properly! #$this->doc = str_replace(array('', '', '', ""), '', $this->doc); #$this->doc = str_replace(array('

', '', '', ""), '', $this->doc); #$this->doc = str_replace('

', '', $this->doc); if (DEBUG) { // $this->doc = self::remove_whitespace(''.$this->doc); // does not work. $this->doc = htmlentities($this->doc); echo '
Tag
(Wiki)
TypeArgsOutput
(Mellel)
'; echo '
'.$this->doc.'
'; } $template = file_get_contents(dirname(__FILE__).'/template.txt'); $this->doc = str_replace('{{CONTENT}}', $this->doc, $template); // $this->doc = str_replace('{{WIKIPAGE}}', str_replace(array('http://', 'https://'), '', DOKU_URL).'/'.$ID, $this->doc); // $this->doc = str_replace('{{WIKIDATE}}', date('d.m.Y', $INFO['meta']['date']['created']).' by '.$INFO['meta']['last_change']['user'], $this->doc); $user = $INFO['meta']['last_change']['user']; setlocale (LC_TIME, 'de_DE@euro', 'de_DE', 'de', 'ge'); $changed_at = date('D d.m.Y', $INFO['meta']['date']['modified']); $this->doc = str_replace('{{EDITED_AT}}', $changed_at, $this->doc); $this->doc = str_replace('{{EDITED_BY}}', $user, $this->doc); $url = str_replace(array('http://', 'https://'), '', DOKU_URL).'/'.$ID; if (strlen($url) > 86) { $url = str_pad($url, 86, '', STR_PAD_LEFT); } $this->doc = str_replace('{{WIKIURL}}', $url, $this->doc); // $this->doc = str_replace(); self::xml_errors($this->doc); $this->doc = self::remove_whitespace($this->doc); $zip = !DEBUG; if ($zip AND class_exists('ZipArchive')) { $zip = new ZipArchive(); $tmpZipFile = tempnam(sys_get_temp_dir().'/', 'aaa_inge_wiki_2_mellel_render_'); $res = $zip->open($tmpZipFile, ZipArchive::CREATE); if ($res === TRUE) { $zip->addFromString('main.xml', $this->doc); $zip->addFromString('.redlex', ''); $zip->close(); $this->doc = file_get_contents($tmpZipFile); @unlink($tmpZipFile); } } // This does not work properly #plugin_enable('highlight'); if ($this->opened != 0) { die('Wrong number of opened and closed tags!'); } if (DEBUG) { exit; } } function __call($name, $arguments) { if (in_array('highlight', plugin_list())) { die('ERROR: highlight loaded'); } require dirname(__FILE__).'/mapping.php'; $this->conf['m'] = $m; $m = $this->conf['m']; $args = func_get_args(); array_shift($args); $args = $args[0]; if (substr($name, -5) === '_open') { $type = 'OPEN'; $multi = true; $this->opened++; } elseif (substr($name, -6) === '_close') { $type = 'CLOSE'; $multi = true; $this->opened--; } else { $type = 'SINGLE'; $multi = false; } $tag = str_replace(array('_open', '_close'), '', $name); // not nice but short // Footnote if (!isset($this->footnote_open)) { $this->footnote_open = false; } if ($tag == 'footnote') { $this->footnote_open = $type == 'OPEN'; } if (isset($m[$tag])) { $mapping = $m[$tag]; } else { foreach ($m as $key => $value) { if (in_array($tag, $value['alias'])) { $mapping = $m[$key]; break; } } } if (!is_array($mapping)) { echo 'No mapping found for function "'.$name.'()" and tag "'.$tag.'"'.PHP_EOL; $this->doc = 'NO MAPPING FOUND'.$this->doc; exit; } // Use different template when p tag (paragraph) is open if (($this->pTagOpen OR $this->sectionTagOpen) AND isset($mapping['template_p_open'])) { $mapping['template'] = $mapping['template_p_open']; } // Special template for Headline level 1 if (in_array($name, array('header', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) { if ($args[1] == 1) { $mapping['template'] = $mapping['template_level_0']; } else { // Reduce level by 1 $args[1]--; } } // Get the corresponding part of the template $templateParts = explode($mapping['replacement'], $mapping['template']); switch ($type) { case 'OPEN': $doc = self::cleanTemplate($templateParts[0]); break; case 'CLOSE': $doc = self::cleanTemplate($templateParts[1]); break; case 'SINGLE': // $args[0] = str_replace('"', '"', $args[0]); // seems not to work in headlines $args[0] = str_replace('&', '&', $args[0]); $args[0] = str_replace('\'', ''', $args[0]); $args[0] = str_replace('<', '<', $args[0]); $args[0] = str_replace('>', '>', $args[0]); if (isset($args[1]) AND (strpos($name, 'link') != false)) { $args[1] = str_replace('&', '&', $args[1]); $args[1] = str_replace('\'', ''', $args[1]); $args[1] = str_replace('<', '<', $args[1]); $args[1] = str_replace('>', '>', $args[1]); } if ($name == 'emaillink') { $args[0] = 'mailto:'.$args[0]; } // Add link text if there is none if (($name === 'internallink' OR $name === 'externallink' OR $name === 'emaillink') AND empty($args[1])) { $args[1] = $args[0]; } // Link text " -> &qout; if (($name === 'internallink' OR $name === 'externallink' OR $name === 'emaillink') AND empty($args[1])) { $args[1] = str_replace('"', '"', $args[1]); } // Full URL for internal links if ($name === 'internallink') { $args[0] = DOKU_URL.$args[0]; } // Code linebreaks if ($name === 'code') { $args[0] = str_replace("\n", '', $args[0]); } // Replace linebreaks with a single space // ??? $args[0] = preg_replace("~ {0,1}\n~", ' ', $args[0]); // Geschützte Leerzeichen für "S. 1234" // $args[0] = preg_replace('~\sS\.([ ]{1})\d+~', '', $args[0]); // Seems not to work // Geviertstrich und Halbgeviertstrich // TODO utf8 codes possible? // TODO longer lines like "hr" should be rendered first to not confuse this $args[0] = str_replace(array('---', '--'), array('—', '–'), $args[0]); // Auslassungspunkte $args[0] = str_replace(array('...'), array('…'), $args[0]); // If not header do replace if (!in_array($name, array('header', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) { $args[0] = str_replace('"', '"', $args[0]); // This might depend on the way " are used in the XML template!!! } // Highlight // This is incompatible with the highlight plugin. // make sure in /lib/plugins/highlight/syntax.php // "if (strpos($_SERVER['REQUEST_URI'], '_export/mellelexport') !== false) {} else {" is added at the top! // There might be a caching problem! When it does not show the highlighted text try to add "&dummy=123" to the download URL if (preg_match('~<hi ~', $args[0])) { // <hi #ff4500>bunt</hi> // U = not greedy $args[0] = preg_replace('~<hi #([a-zA-Z0-9]+)>(.*)</hi>~Ui', '$2', $args[0]); // $args[0] = preg_replace('~<hi #[a-zA-Z0-9]+>~', '', $args[0]); // Replace marker with Mellel marker ids $args[0] = preg_replace_callback('~marker=\'([a-zA-Z0-9]+)\'~', 'callback_marker', $args[0]); } $args[0] = str_replace('</hi>', '', $args[0]); $string = str_replace($mapping['replacement'], $args[0], self::cleanTemplate($mapping['template'])); $doc = $string; break; default: die('No type set'); } // Formating within footnote text if ($this->footnote_open AND $tag != 'footnote') { $doc = str_replace(' style="cs-0"', ' style="cs-6"', $doc); } // Check the given arguments and parse additional information if (!$multi) { array_shift($args); // remove the first entry } if (isset($args)) { $doc = str_replace($mapping['subpattern'], $args, $doc); } // Set header length if ($tag === 'header' OR (isset($key) AND $key === 'header')) { if (function_exists('mb_strlen')) { $hederLength = mb_strlen($arguments[0]); } else { $hederLength = strlen($arguments[0]); } $doc = str_replace('{{LENGTH}}', $hederLength + 10 /* don't know the algorithmus, 10 is an assumption */, $doc); } // :?: --> rendered as a yellow questionmark image $doc = str_replace(array(':?:'), array('?'), $doc); if (DEBUG) { // all args excluded the first one $tmp_args = func_get_args(); array_shift($tmp_args); $tmp_args = $tmp_args[0]; echo ''.$tag.''.$type.'  '.var_export($tmp_args, 1).''.trim(htmlentities($doc, NULL, 'UTF-8')).''; } $this->doc .= $doc; $this->lastTag = $name; if ($tag == 'p') { if ($type == 'OPEN') { $this->pTagOpen = TRUE; } else { $this->pTagOpen = FALSE; } } if ($tag == 'section') { if ($type == 'OPEN') { $this->sectionTagOpen = TRUE; } else { $this->sectionTagOpen = FALSE; } } } static function cleanTemplate($xml) { return preg_replace('~>[\r\n]\s*<~', '><', $xml); // no trim()! trim here deletes valid whitespaces } static function xml_errors ($xml) { libxml_use_internal_errors(true); $doc = new DOMDocument('1.0', 'utf-8'); $doc->loadXML( $xml ); $errors = libxml_get_errors(); if (count($errors) > 0) { echo 'Details'; echo '
';
            $lines = explode("\n", $xml);
            $padding = 70;
            foreach($errors as $error) {
                $line = $lines[($error->line - 1)];
                
                $start = ($error->column - $padding) > 0 ? ($error->column - $padding) : 0;
                
                echo trim($error->message).'
'; echo htmlentities(substr($line, $start, $padding * 2)).'...
'; $column = $error->column - $start - 1; echo str_pad('', $column, '-').'^'; echo '

'; } echo '
'; echo 'XML Error(s):'; echo '
';
            echo var_export($errors, 1);
            echo '
'; echo 'Plain XML:'; echo '
';
            echo htmlentities($xml);
            echo '
'; exit; } } static function remove_whitespace($xml) { libxml_use_internal_errors(true); $doc = new DOMDocument('1.0', 'utf-8'); $doc->loadXML( $xml ); if (!DEBUG) { $doc->preserveWhiteSpace = FALSE; $doc->formatOutput = FALSE; } else { $doc->preserveWhiteSpace = FALSE; $doc->formatOutput = TRUE; } return self::cleanTemplate($doc->saveXML()); } // Dummy mappings of method to __call() function render_TOC() { return ''; } function toc_additem($id, $text, $level) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function header($text, $level, $pos) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function section_open($level) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function section_close() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function cdata($text) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function p_open() { #var_dump(func_get_args()); call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args())); } function p_close() {#var_dump(func_get_args()); call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function linebreak() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function hr() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function strong_open() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function strong_close() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function emphasis_open() { #var_dump(__FUNCTION__); call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function emphasis_close() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function underline_open() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function underline_close() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function monospace_open() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function monospace_close() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function subscript_open() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function subscript_close() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function superscript_open() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function superscript_close() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function deleted_open() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function deleted_close() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function footnote_open() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function footnote_close() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function listu_open() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function listu_close() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function listo_open() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function listo_close() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function listitem_open($level) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function listitem_close() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function listcontent_open() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function listcontent_close() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function unformatted($text) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function php($text) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function phpblock($text) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function html($text) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function htmlblock($text) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function preformatted($text) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function quote_open() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function quote_close() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function file($text, $lang = null, $file = null ) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function code($text, $lang = null, $file = null ) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function acronym($acronym) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function smiley($smiley) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function wordblock($word) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function entity($entity) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} // 640x480 ($x=640, $y=480) function multiplyentity($x, $y) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function singlequoteopening() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function singlequoteclosing() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function apostrophe() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function doublequoteopening() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function doublequoteclosing() {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} // $link like 'SomePage' function camelcaselink($link) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function locallink($hash, $name = NULL) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} // $link like 'wiki:syntax', $title could be an array (media) function internallink($link, $title = NULL) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} // $link is full URL with scheme, $title could be an array (media) function externallink($link, $title = NULL) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function rss ($url,$params) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} // $link is the original link - probably not much use // $wikiName is an indentifier for the wiki // $wikiUri is the URL fragment to append to some known URL function interwikilink($link, $title = NULL, $wikiName, $wikiUri) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} // Link to file on users OS, $title could be an array (media) function filelink($link, $title = NULL) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} // Link to a Windows share, , $title could be an array (media) function windowssharelink($link, $title = NULL) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} // function email($address, $title = NULL) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function emaillink($address, $name = NULL) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function internalmedia ($src, $title=NULL, $align=NULL, $width=NULL, $height=NULL, $cache=NULL, $linking=NULL) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function externalmedia ($src, $title=NULL, $align=NULL, $width=NULL, $height=NULL, $cache=NULL, $linking=NULL) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function internalmedialink ( $src,$title=NULL,$align=NULL,$width=NULL,$height=NULL,$cache=NULL ) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function externalmedialink( $src,$title=NULL,$align=NULL,$width=NULL,$height=NULL,$cache=NULL ) {call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function table_open($maxcols = null, $numrows = null, $pos = null){call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function table_close($pos = null){call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function tablerow_open(){call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function tablerow_close(){call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function tableheader_open($colspan = 1, $align = NULL, $rowspan = 1){call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function tableheader_close(){call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function tablecell_open($colspan = 1, $align = NULL, $rowspan = 1){call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} function tablecell_close(){call_user_func_array(array($this, '__call'), array(__FUNCTION__, func_get_args()));} }