Revision [20636]

This is an old revision of CKeditor4Wikka made by MaiGre on 2009-05-19 12:35:53.

 

CKeditor as Wikka Editor


The new 3.x WYSIWYG Html editor by Frederico Caldeira Knabbe is about to be released : http://ckeditor.com/

This project - CKeditor (renamed from FCKeditor since 3.0) - is a complete editor with filemanager.
It allows to edit page as a rich document, and ouput it as Html.

This is a mature project (waiting for the 3.0 release) and it works well.
FCK team has already start a mod of the editor (version 2.6) to have wikitext output for MediWiki,
so i decided to start a CKeditor4Wikka project.

The big difference with the FCK+MediaWiki project is that
i didn't want to change anything in the FCK core because this project change really often
so i would like to have a combo that we can easily update from both sides (Wikka and CK).
Example : CKeditor 3.0 will be radically different than FCKeditor 2.x :)

So CKeditor will run normally with HTML output, but i am working on a formatter
that translate common html output into Wikka-wikitext.

This is fckoutput.php and it is use when saving the page.

When starting edition, we need also Html to feed the editor with the current state of the page.
I did a modification of the usual wakka.php formatter, in order to desactivate some translations
as actions (the editor doesn't need included actions).

This is fckinput.php and it is use when entering the Edit mode.

I began to learn Regexp since yesterday so my formatter is not optimized (i ask for your help...)
But it seems to work :)

As the final content is saved as wikitext, we can easily switch between WikiEdit and CKeditor.

You can of course use Wikitext syntax in Html mode !

Not all features are implemented, here is the TODO list :

There is also features from CKeditor not supported by Wikka (that can be hack by creating new actions!)

The TODO list features are still available if you choose WikiEdit editor mode
but it will not have an effect in CKeditor. You will see it with wikitext syntax.

You can find here the edit.php hack to include CKeditor,
fckinput.php : the wakka light formatter (on editor start up)
fckoutput.php : the reverse html2wikitext formatter (before saving in database)

Install

REPLACE in /handlers/page/edit.php - line 271

$output .=
           
            $this->FormOpen('edit').
            '<input type="hidden" name="previous" value="'.$previous.'" />'."\n".
            // We need to escape ALL entity refs before display so we display them _as_ entities instead of interpreting them
            // hence hsc_secure() instead of htmlspecialchars_ent() which UNescapes entities!
            // JW/2007-02-20: why is this? wouldn't it be  easier for the person editing to show actual characters instead of entities?
            '<div id="textarea_container">'."\n".
            '<textarea id="body" name="body" rows="100" cols="20">'.$this->hsc_secure($body).'</textarea>'."\n".    #427
            '</div>'."\n";


WITH :

//CKeditor !
$output .=

            $this->FormOpen('edit').
            '<input type="hidden" name="previous" value="'.$previous.'" />'."\n".
            '<script type="text/javascript" src="handlers/page/ckeditor/ckeditor.js"></script>'."\n".
            '<div id="textarea_container">'."\n".          
            '<textarea name="body">'.$this->Format($body,'fckinput').'</textarea>'."\n".
            '</div>'."\n".
            '<script type="text/javascript"> CKEDITOR.replace( \'body\' ) </script>';
//end CKeditor !


the fckinput.php file :
<?php
/**  fckinput.php          
  * /formatters/                

 * Wikka Formatting Engine
 * Mod of the wakka.php formatter to feed FCKeditor input html
 *
 * -> disable mindmap
 * -> disable code // TODO: enable CODE!
 * -> disable literal
 * -> disable action
 * -> enable action only for image - waiting for a better image support :)
 * -> disable InterWiki
 * -> disable urls
 *
 * by Thomas Bohl - MaiGre
 *
 */


// i18n strings
if (!defined('GRABCODE_BUTTON_VALUE')) define('GRABCODE_BUTTON_VALUE', 'Grab');
if (!defined('GRABCODE_BUTTON_TITLE')) define('GRABCODE_BUTTON_TITLE', 'Download %s');

// code block patterns
if (!defined('PATTERN_OPEN_BRACKET')) define('PATTERN_OPEN_BRACKET', '\(');
if (!defined('PATTERN_FORMATTER')) define('PATTERN_FORMATTER', '([^;\)]+)');
if (!defined('PATTERN_LINE_NUMBER')) define('PATTERN_LINE_NUMBER', '(;(\d*?))?');
if (!defined('PATTERN_FILENAME')) define('PATTERN_FILENAME', '(;([^\)\x01-\x1f\*\?\"<>\|]*)([^\)]*))?');
if (!defined('PATTERN_CLOSE_BRACKET')) define('PATTERN_CLOSE_BRACKET', '\)');
if (!defined('PATTERN_CODE')) define('PATTERN_CODE', '(.*)');

// Note: all possible formatting tags have to be in a single regular expression for this to work correctly.

if (!function_exists("wakka2callback")) # DotMG [many lines] : Unclosed tags fix!
{
    function wakka2callback($things)
    {
        $thing = $things[1];
        $result='';
        $valid_filename = '';
       
        static $oldIndentLevel = 0;
        static $oldIndentLength= 0;
        static $indentClosers = array();
        static $newIndentSpace= array();
        static $br = 1;
        static $trigger_bold = 0;
        static $trigger_italic = 0;
        static $trigger_underline = 0;
        static $trigger_monospace = 0;
        static $trigger_notes = 0;
        static $trigger_strike = 0;
        static $trigger_inserted = 0;
        static $trigger_deleted = 0;
        static $trigger_floatl = 0;
        static $trigger_keys = 0;
        static $trigger_strike = 0;
        static $trigger_inserted = 0;
        static $trigger_center = 0;
        static $trigger_l = array(-1, 0, 0, 0, 0, 0);
        static $output = '';
        static $invalid = '';
        static $curIndentType;

        global $wakka;

        if ((!is_array($things)) && ($things == 'closetags'))
        {
            if ($trigger_strike % 2) echo ('</span>');
            if ($trigger_notes % 2) echo ('</span>');
            if ($trigger_inserted % 2) echo ('</div>');
            if ($trigger_deleted % 2) echo ('</div>');
            if ($trigger_underline % 2) echo('</span>');
            if ($trigger_floatl % 2) echo ('</div>');
            if ($trigger_center % 2) echo ('</div>');
            if ($trigger_italic % 2) echo('</em>');
            if ($trigger_monospace % 2) echo('</tt>');
            if ($trigger_bold % 2) echo('</strong>');
            for ($i = 1; $i<=5; $i ++)
                if ($trigger_l[$i] % 2) echo ("</h$i>");
            $trigger_bold = $trigger_center = $trigger_floatl = $trigger_inserted = $trigger_deleted = $trigger_italic = $trigger_keys = 0;
            $trigger_l = array(-1, 0, 0, 0, 0, 0);
            $trigger_monospace = $trigger_notes = $trigger_strike = $trigger_underline = 0;
            return;
        }
        // convert HTML thingies
        if ($thing == "<")
            return "&lt;";
        else if ($thing == ">")
            return "&gt;";
        // float box left
        else if ($thing == "<<")
        {
            return (++$trigger_floatl % 2 ? "<div class=\"floatl\">\n" : "\n</div>\n");
        }
        // float box right
        else if ($thing == ">>")
        {
            return (++$trigger_floatl % 2 ? "<div class=\"floatr\">\n" : "\n</div>\n");
        }
        // clear floated box
        else if ($thing == "::c::")
        {
            return ("<div class=\"clear\">&nbsp;</div>\n");
        }
        // keyboard
        else if ($thing == "#%")
        {
            return (++$trigger_keys % 2 ? "<kbd class=\"keys\">" : "</kbd>");
        }
        // bold
        else if ($thing == "**")
        {
            return (++$trigger_bold % 2 ? "<strong>" : "</strong>");
        }
        // italic
        else if ($thing == "//")
        {
            return (++$trigger_italic % 2 ? "<em>" : "</em>");
        }
        // underlinue
        else if ($thing == "__")
        {
            return (++$trigger_underline % 2 ? "<u>" : "</u>");
        }
        // monospace
        else if ($thing == "##")
        {
            return (++$trigger_monospace % 2 ? "<tt>" : "</tt>");
        }
        // notes
        else if ($thing == "''")
        {
            return (++$trigger_notes % 2 ? "<span class=\"notes\">" : "</span>");
        }
        // strikethrough
        else if ($thing == "++")
        {
            return (++$trigger_strike % 2 ? "<strike>" : "</strike>");
        }
        // additions
        else if ($thing == "&pound;&pound;")
        {
            return (++$trigger_inserted % 2 ? "<ins>" : "</ins>");
        }
        // deletions
        else if ($thing == "&yen;&yen;")
        {
            return (++$trigger_deleted % 2 ? "<del>" : "</del>");
        }
        // center
        else if ($thing == "@@")
        {
            return (++$trigger_center % 2 ? "<div style=\"text-align: center;\">\n" : "\n</div>\n");
        }
        // urls
        else if (preg_match("/^([a-z]+:\/\/\S+?)([^[:alnum:]^\/])?$/", $thing, $matches))
        {
            $url = $matches[1];
            /* Inline images are disabled for security reason, use {{image action}} #142
            But if you still need this functionality, update this file like below
            if (preg_match("/\.(gif|jpg|png|svg)$/si", $url)) {
                return '<img src="'.$wakka->Link($url).'" alt="image" />'.$wakka->htmlspecialchars_ent($matches[2]);
            } else */

            // Mind Mapping Mod
            if (preg_match("/\.(mm)$/si", $url)) { #145
                return $wakka->Action("mindmap ".$url);
            } else
                $link = $wakka->Link($url);
                if(isset($matches[2])) $link .= $matches[2];
                return $link;
        }
        // header level 5
        else if ($thing == "==")
        {
                $br = 0;
                return (++$trigger_l[5] % 2 ? "<h5>" : "</h5>\n");
        }
        // header level 4
        else if ($thing == "===")
        {
                $br = 0;
                return (++$trigger_l[4] % 2 ? "<h4>" : "</h4>\n");
        }
        // header level 3
        else if ($thing == "====")
        {
                $br = 0;
                return (++$trigger_l[3] % 2 ? "<h3>" : "</h3>\n");
        }
        // header level 2
        else if ($thing == "=====")
        {
                $br = 0;
                return (++$trigger_l[2] % 2 ? "<h2>" : "</h2>\n");
        }
        // header level 1
        else if ($thing == "======")
        {
                $br = 0;
                return (++$trigger_l[1] % 2 ? "<h1>" : "</h1>\n");
        }
        // forced line breaks
        else if ($thing == "---")
        {
            return "<br />";
        }
        // escaped text
        else if (preg_match("/^\"\"(.*)\"\"$/s", $thing, $matches))
        {//"\{\{.*?\}\}|".                      # action
            $allowed_double_doublequote_html = $wakka->GetConfigValue("double_doublequote_html");
            if ($allowed_double_doublequote_html == 'safe')
            {
                $filtered_output = $wakka->ReturnSafeHTML($matches[1]);
                return $filtered_output;
            }
            elseif ($allowed_double_doublequote_html == 'raw')
            {
                return $matches[1];
            }
            else
            {
                return $wakka->htmlspecialchars_ent($matches[1]);
            }
        }
        // code text
        else if (preg_match("/^
(.*?)
$/s", $thing, $matches))
		{
			/*
			* Note: this routine is rewritten such that (new) language formatters
			* will automatically be found, whether they are GeSHi language config files
			* or "internal" Wikka formatters.
			* Path to GeSHi language files and Wikka formatters MUST be defined in config.
			* For line numbering (GeSHi only) a starting line can be specified after the language
			* code, separated by a ; e.g., 
(php;27)....
.
			* Specifying >= 1 turns on line numbering if this is enabled in the configuration.
			* An optional filename can be specified as well, e.g. 
(php;27;myfile.php)....
			* This filename will be used by the grabcode handler.			
			*/
			$output = ''; //reinitialize variable
			$code = $matches[1];
			// if configuration path isn't set, make sure we'll get an invalid path so we
			// don't match anything in the home directory
			$geshi_hi_path = isset($wakka->config['geshi_languages_path']) ? $wakka->config['geshi_languages_path'] : '/:/';
			$wikka_hi_path = isset($wakka->config['wikka_highlighters_path']) ? $wakka->config['wikka_highlighters_path'] : '/:/';
			// check if a language (and an optional starting line or filename) has been specified
			if (preg_match('/^'.PATTERN_OPEN_BRACKET.PATTERN_FORMATTER.PATTERN_LINE_NUMBER.PATTERN_FILENAME.PATTERN_CLOSE_BRACKET.PATTERN_CODE.'$/s', $code, $matches))
			{
				list(, $language, , $start, , $filename, $invalid, $code) = $matches;
			}
			// get rid of newlines at start and end (and preceding/following whitespace)
			// Note: unlike trim(), this preserves any tabs at the start of the first "real" line
			$code = preg_replace('/^\s*\n+|\n+\s*$/','',$code);
			
			// check if GeSHi path is set and we have a GeSHi highlighter for this language
#			if (isset($language) && isset($wakka->config['geshi_path']) && file_exists($geshi_hi_path.'/'.$language.'.php'))
			if (isset($language) && isset($wakka->config['geshi_path']) && file_exists($geshi_hi_path.DIRECTORY_SEPARATOR.$language.'.php')) #89
			{
				// check if specified filename is valid and generate code block header
				if (isset($filename) && strlen($filename) > 0 && strlen($invalid) == 0) # #34 TODO: use central regex library for filename validation
				{
					$valid_filename = $filename;
					// create code block header
					$output .= '<div class="code_header">';
					// display filename and start line, if specified
					$output .= $filename;
					if (strlen($start)>0)
					{
						$output .= ' (line '.$start.')';
					}
					$output .= '</div>'."\n";
				}
				// use GeSHi for highlighting
				$output .= $wakka->GeSHi_Highlight($code, $language, $start);
			}
			// check Wikka highlighter path is set and if we have an internal Wikka highlighter
#			elseif (isset($language) && isset($wakka->config['wikka_formatter_path']) && file_exists($wikka_hi_path.'/'.$language.'.php') && 'wakka' != $language)
			elseif (isset($language) && isset($wakka->config['wikka_formatter_path']) && file_exists($wikka_hi_path.DIRECTORY_SEPARATOR.$language.'.php') && 'wakka' != $language) #89
			{
				// use internal Wikka highlighter
				$output = '<div class="code">'."\n";
				$output .= $wakka->Format($code, $language);
				$output .= "</div>\n";
			}
			// no language defined or no formatter found: make default code block;
			// IncludeBuffered() will complain if 'code' formatter doesn't exist
			else
			{
				$output = '<div class="code">'."\n";
				$output .= $wakka->Format($code, 'code');
				$output .= "</div>\n";
			}

			// display grab button if option is set in the config file
			if ($wakka->config['grabcode_button'] == '1')
			{
				$output .= $wakka->FormOpen("grabcode");
				// build form
				$output .= '<input type="submit" class="grabcode" name="save" value="'.GRABCODE_BUTTON_VALUE.'" title="'.rtrim(sprintf(GRABCODE_BUTTON_TITLE, $valid_filename)).'" />';
				$output .= '<input type="hidden" name="filename" value="'.urlencode($valid_filename).'" />';
				$output .= '<input type="hidden" name="code" value="'.urlencode($code).'" />';
				$output .= $wakka->FormClose();
			}
			// output
			return $output;
		}
		// forced links
		// \S : any character that is not a whitespace character
		// \s : any whitespace character
		else if (preg_match("/^\[\[(\S*)(\s+(.+))?\]\]$/s", $thing, $matches))		# recognize forced links across lines
		{
			if (isset($matches[1])) // url?
			{
				//if ($url!=($url=(preg_replace("/@@|&pound;&pound;||\[\[/","",$url))))$result="</span>";
				$text = '';
				$url = $matches[1];
				if (isset($matches[3])) $text = $matches[3]; // forced link title
				//$text=preg_replace("/@@|&pound;&pound;|\[\[/","",$text);
				return $result.$wakka->Link($url, "", $text);
			}
			else
			{
				return "";
			}
		}
		// indented text
		elseif (preg_match("/(^|\n)([\t~]+)(-|&|([0-9a-zA-Z]+)\))?(\n|$)/s", $thing, $matches))
		{
			// new line
			$result .= ($br ? "<br />\n" : "\n");

			// we definitely want no line break in this one.
			$br = 0;

			// find out which indent type we want
			$newIndentType = $matches[3];
			if (!$newIndentType) { $opener = "<div class=\"indent\">"; $closer = "</div>"; $br = 1; }
			elseif ($newIndentType == "-") { $opener = "<ul><li>"; $closer = "</li></ul>"; $li = 1; }
			elseif ($newIndentType == "&") { $opener = "<ul class=\"thread\"><li>"; $closer = "</li></ul>"; $li = 1; } #inline comments
			else
			{
				if     (ereg('[0-9]', $newIndentType[0])) { $newIndentType = '1'; }
				elseif (ereg('[IVX]', $newIndentType[0])) { $newIndentType = 'I'; }
				elseif (ereg('[ivx]', $newIndentType[0])) { $newIndentType = 'i'; }
				elseif (ereg('[A-Z]', $newIndentType[0])) { $newIndentType = 'A'; }
				elseif (ereg('[a-z]', $newIndentType[0])) { $newIndentType = 'a'; }

				$opener = '<ol type="'.$newIndentType.'"><li>';
				$closer = '</li></ol>';
				$li = 1;
			}

			// get new indent level
			$newIndentLevel = strlen($matches[2]);
			if (($newIndentType != $curIndentType) && ($oldIndentLevel > 0))
			{
				for (; $oldIndentLevel > $newIndentLevel; $oldIndentLevel --)
				{
					$result .= array_pop($indentClosers);
				}
			}
			if ($newIndentLevel > $oldIndentLevel)
			{
				for ($i = 0; $i < $newIndentLevel - $oldIndentLevel; $i++)
				{
					$result .= $opener;
					array_push($indentClosers, $closer);
				}
			}
			else if ($newIndentLevel < $oldIndentLevel)
			{
				for ($i = 0; $i < $oldIndentLevel - $newIndentLevel; $i++)
				{
					$result .= array_pop($indentClosers);
				}
			}

			$oldIndentLevel = $newIndentLevel;

			if (isset($li) && !preg_match("/".str_replace(")", "\)", $opener)."$/", $result))
			{
				$result .= "</li><li>";
			}

			$curIndentType = $newIndentType;
			return $result;
		}
		// new lines
		else if ($thing == "\n")
		{
			// if we got here, there was no tab in the next line; this means that we can close all open indents.
			$c = count($indentClosers);
			for ($i = 0; $i < $c; $i++)
			{
				$result .= array_pop($indentClosers);
				$br = 0;
			}
			$oldIndentLevel = 0;
			$oldIndentLength= 0;
			$newIndentSpace=array();

			$result .= ($br ? "<br />\n" : "\n");
			$br = 1;
			return $result;
		}
		// Actions
		else if (preg_match("/^\{\{(.*?)\}\}$/s", $thing, $matches))
		{
			if ($matches[1])
				return $wakka->Action($matches[1]);
			else
				return "{{}}";
		}
		// interwiki links!
		else if (preg_match("/^[A-ZÄÖÜ][A-Za-zÄÖÜßäöü]+[:]\S*$/s", $thing))
		{
			return $wakka->Link($thing);
		}
		// wiki links!
		else if (preg_match("/^[A-ZÄÖÜ]+[a-zßäöü]+[A-Z0-9ÄÖÜ][A-Za-z0-9ÄÖÜßäöü]*$/s", $thing))
		{
			return $wakka->Link($thing);
		}
		// separators
		else if (preg_match("/-{4,}/", $thing, $matches))
		{
			// TODO: This could probably be improved for situations where someone puts text on the same line as a separator.
			//	   Which is a stupid thing to do anyway! HAW HAW! Ahem.
			$br = 0;
			return "<hr />\n";
		}
		// mind map xml
		else if (preg_match("/^<map.*<\/map>$/s", $thing))
		{
			return $wakka->Action("mindmap ".$wakka->Href()."/mindmap.mm");
		}
		// if we reach this point, it must have been an accident.
		return $thing;
	}
}

$text = str_replace("\r\n", "\n", $text);

// replace 4 consecutive spaces at the beginning of a line with tab character
// $text = preg_replace("/\n[ ]{4}/", "\n\t", $text); // moved to edit.php

//if ($this->method == "show") $mind_map_pattern = "<map.*?<\/map>|"; else $mind_map_pattern = "";

$text = preg_replace_callback(
	"/(".
	//"
.*?
|".     	# code
	//"\"\".*z\"\"|".	# literal
	//$mind_map_pattern. 
	"\[\[[^\[]*?\]\]|".	# forced link
	"-{4,}|---|".		# separator (hr)
	//"\b[a-z]+:\/\/\S+|".	# URL
	"\*\*|\'\'|\#\#|\#\%|@@|::c::|\>\>|\<\<|&pound;&pound;|&yen;&yen;|\+\+|__|<|>|\/\/|".	# Wiki markup
	"======|=====|====|===|==|".					# headings
	"(^|\n)([\t~]+)(-(?!-)|&|([0-9]+|[a-zA-Z]+)\))?|".		# indents and lists
	//"\{\{.*?\}\}|".						# action
	"\{\{image.*?\}\}|".						# action image
	//"\b[A-ZÄÖÜ][A-Za-zÄÖÜßäöü]+[:](?![=_])\S*\b|".		# InterWiki link
	"\b([A-ZÄÖÜ]+[a-zßäöü]+[A-Z0-9ÄÖÜ][A-Za-z0-9ÄÖÜßäöü]*)\b|".	# CamelWords
	"\n".								# new line
	")/ms", "wakka2callback", $text."\n"); 				#append \n (#444)

// we're cutting the last <br />
$text = preg_replace("/<br \/>$/","", $text);

echo ($text);
wakka2callback('closetags');

?>


fckoutput.php
<?php
/**  fckoutput.php          
  * /formatters/                

 * Wikka un-Formatting Engine
 * Mod of the wakka.php formatter to transform hmtl from FCKeditor output to wikitext !
 *
 * TODO: For WikiEdit support -> colored text action, numered list, thread list, tables, mindmap, code, literal
 * TODO: For CKeditor support -> colored text, right align, justify, anchor, image, flash, tables, fonts, text-size, background color
 *
 *
 *
 *
 * by Thomas Bohl - MaiGre
 *
 */


// i18n strings
if (!defined('GRABCODE_BUTTON_VALUE')) define('GRABCODE_BUTTON_VALUE', 'Grab');
if (!defined('GRABCODE_BUTTON_TITLE')) define('GRABCODE_BUTTON_TITLE', 'Download %s');

// code block patterns
if (!defined('PATTERN_OPEN_BRACKET')) define('PATTERN_OPEN_BRACKET', '\(');
if (!defined('PATTERN_FORMATTER')) define('PATTERN_FORMATTER', '([^;\)]+)');
if (!defined('PATTERN_LINE_NUMBER')) define('PATTERN_LINE_NUMBER', '(;(\d*?))?');
if (!defined('PATTERN_FILENAME')) define('PATTERN_FILENAME', '(;([^\)\x01-\x1f\*\?\"<>\|]*)([^\)]*))?');
if (!defined('PATTERN_CLOSE_BRACKET')) define('PATTERN_CLOSE_BRACKET', '\)');
if (!defined('PATTERN_CODE')) define('PATTERN_CODE', '(.*)');



if (!function_exists("html2wikitext"))
{
    function html2wikitext($things)
    {
        $thing = $things[1];
        $result='';
        $valid_filename = '';
       
        static $openedDIV = array();
        static $openedSPAN = array();      
       
        global $wakka;
       
        // TODO : close wikiTag !
        /*if ((!is_array($things)) && ($things == 'closetags'))
        {
            if ($trigger_strike % 2) echo ('</span>');
            if ($trigger_notes % 2) echo ('</span>');
            if ($trigger_inserted % 2) echo ('</div>');
            if ($trigger_deleted % 2) echo ('</div>');
            if ($trigger_underline % 2) echo('</span>');
            if ($trigger_floatl % 2) echo ('</div>');
            if ($trigger_center % 2) echo ('</div>');
            if ($trigger_italic % 2) echo('</em>');
            if ($trigger_monospace % 2) echo('</tt>');
            if ($trigger_bold % 2) echo('</strong>');
            for ($i = 1; $i<=5; $i ++)
                if ($trigger_l[$i] % 2) echo ("</h$i>");
            $trigger_bold = $trigger_center = $trigger_floatl = $trigger_inserted = $trigger_deleted = $trigger_italic = $trigger_keys = 0;
            $trigger_l = array(-1, 0, 0, 0, 0, 0);
            $trigger_monospace = $trigger_notes = $trigger_strike = $trigger_underline = 0;
            return;
        }
        */


       
        //close current div
        if ($thing == '</div>')    
            {              
                if(count($openedDIV[0]) >= 1) return array_shift($openedDIV);
                else return $thing;
            }
        else if ($thing == '</span>')      
            {              
                if(count($openedSPAN[0]) >= 1) return array_shift($openedSPAN);
                else return $thing;
            }
        else if ($thing == "<div>")
            {
                array_unshift($openedDIV,"\n");    
                return "";
            }
        // separator       
        else if ($thing == "<hr />")
            return "----\n";

        else if (preg_match("/^<\/?strong>$/i", $thing))
            return "**";

        else if (preg_match("/^<\/?em>$/i", $thing))
            return "//";

        else if (preg_match("/^<\/?tt>$/i", $thing))
            return "##";

        else if (($thing == '</kbd>')||($thing == '<kbd class="keys">'))
            return "#%";

        else if ((preg_match("/^<div style=\"text-align: ?center;\">$/i", $thing)))
            {
                array_unshift($openedDIV,"@@\n");      
                return '@@';
            }

        else if ((preg_match("/^<div style=\"margin-left: ?[2-5]0px;\">$/i", $thing)))
            {
                array_unshift($openedDIV,"\n");    
                return "\t";
            }

        else if ($thing == "<div class=\"clear\">&nbsp;<\/div>")
            return "::c::";
       
        else if (preg_match("/^<div class=\"floatl\">$/i", $thing))
            {
                array_unshift($openedDIV,"<<\n");      
                return '<<';
            }

        else if (preg_match("/^<div class=\"floatr\">$/i", $thing))
            {
                array_unshift($openedDIV,">>\n");      
                return '>>';
            }

        else if (preg_match("#<\/?ins>#", $thing))
            return "&pound;&pound;";

        else if (preg_match("#<\/?del>#", $thing))
            return "&yen;&yen;";

        else if (preg_match("/^<span class=\"strikethrough\">$/i", $thing,$matches))
            {
                array_unshift($openedSPAN,"++");       
                return '++';
            }

        else if (preg_match("/^<span class=\"underline\">$/i", $thing,$matches))
            {
                array_unshift($openedSPAN,"__");       
                return '__';
            }

        else if (preg_match("/^<span class=\"notes\">$/i", $thing,$matches))
            {
                array_unshift($openedSPAN,"''");       
                return "''";
            }

        else if (preg_match("/^<\/?h([1-5])>$/i", $thing, $matches))
            {
                if (preg_match("#\/#", $thing)) $break = "\n";
                else $break = "";          
                if($matches[1] == 5) return '=='.$break;
                else if($matches[1] == 4) return '==='.$break;
                else if($matches[1] == 3) return '===='.$break;
                else if($matches[1] == 2) return '====='.$break;
                else if($matches[1] == 1) return '======'.$break;          
            }

        else if (preg_match("/^<div class=\"indent\">$/i", $thing,$matches))
            {
                array_unshift($openedDIV,"\n");    
                return "\t~- ";
            }

        else if (preg_match("/^<\/?ul>$/i", $thing))
            return "";

        else if ($thing == "<li>")
            return "\t~- ";
       
        else if ($thing == "</li>")
            return "\n";

        else if (preg_match("/^<a .*href=[\"'](.+)[\"'](.*)>(.*)<\/a>$/i", $thing,$matches))
            {      
                //CamelLinks
               
                if (stripos($matches[1],$wakka->config['base_url']) !== FALSE)
                {
                    $camel = explode($wakka->config['base_url'],$matches[1]);
                    $camel = explode('/',$camel[1]);

                    //forced CamelLink?
                    if($matches[3] == $camel[0]) return $camel[0];
                    else return '[['.$camel[0].' '.$matches[3].']]';
                }
                //normal links
                if ($matches[3] == $matches[1]) return '[['.$matches[1].']]';
                else return '[['.$matches[1].' '.$matches[3].']]';
                       
            }
       
        else if ($thing == "<br />")
            return "\n";

        else if (preg_match("/^<\/?u>$/i", $thing))
            return "__";

        else if (preg_match("/^<\/?strike>$/i", $thing))
            return "++";

        // if we reach this point, it must have been an accident.
        return 'bordel';
    }
}


$text =  str_replace("\n", "", $text);
$text =  str_replace("\t", "", $text);
$text =  str_replace("<p", "<div", $text);
$text =  str_replace("</p>", "</div>", $text);

$text = preg_replace_callback(
    "/(".

    //stuff from fckinput.php formatter

    "<hr \/>|".     # separator
    "<\/?strong>|".    
    "<\/?em>|".
    "<\/?tt>|".
    "<kbd class=\"keys\">|<\/kbd>|".
    "<div style=\"text-align: ?center;\">|".
    "<div class=\"clear\">&nbsp;<\/div>|".
    "<div class=\"floatr\">|".
    "<div class=\"floatl\">|".
    "<\/?ins>|".
    "<\/?del>|".
    "<span class=\"strikethrough\">|".
    "<span class=\"underline\">|".
    "<span class=\"notes\">|".                      # Wiki markup
    "<\/?h[1-5]>|".                                 # headings
    "<div class=\"indent\">|".
    "<\/?ul>|".                                 # indents simplified..
    "<li>|".
    "<\/li>|".     
    "<a (.*)href=[\"'].+[\"'].*>(.*)<\/a>|".                    # links
    "<br \/>|".
    "<\/div>|".                                 # new line
    "<\/span>|".   

    //additional stuff from CKeditor AND wikka actions
   
    "<div style=\"margin-left: ?[2-5]0px;\">|".             #tab   
    "<div>|".  
    "<\/?u>|".
    "<\/?strike>".
    //"<img(.*)\/>".                        # action image
   
    ")/msi", "html2wikitext", $text);              

echo ($text);

//html2wikitext('closetags');
?>


There are 4 comments on this page. [Show comments]
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki