Extension:TEX Editor/Code

From MediaWiki.org
Jump to: navigation, search

Copy-How-To

The source code contains special html entities which are not correctly displayed in normal page view therefore you MUST open the page in edit mode for copying the code.

After opening the page in edit mode copy from <source lang="php"> to </source> at the end of the page.

<?php
/**
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/


if( !defined( 'MEDIAWIKI' ) ) {
  die();
}

$wgExtensionCredits['specialpage'][] = array(
        'path' => __FILE__,
	'name' => 'The TeX Box',
	'author' => 'Mafs',
	"version' => '(0.4) 2007',
	'url' => 'https://www.mediawiki.org/wiki/Extension:TeX_Editor',
	'description' => 'a configurable TEX editor for mathematical formulae'

 );

function wfSpecialTexbox() {

	global $wgUser, $wgOut, $wgLang, $wgRequest, $wgScriptPath, $texList;
	
	$wgUser->setOption("math", 0); // render png
	$name = $wgUser->getName();

	$fname = 'wfSpecialTex';
	$texFavorites = "TEX/Favorites";

	$modus = $wgRequest->getVal( 'box' ) ; 

	// load tex favorites from user page ********************
	
	$ti = Title::newFromText($name."/".$texFavorites, 2);
	$ac = new Article($ti);
	if ($ac->exists()) {
		$tf = $ac->getContent(); 
		$tf = explode("\n", $tf);
		
		if (is_array($tf)) {
				foreach	($tf as $favorite) {
					if (preg_match("/^\|([^\-\}].*)/", $favorite, $a) ) $texList[] = explode("||", $a[1]);
				}
		}	
	}
	
	// load tex favorites from default page in main namespace   *******************
	
	if (count($texList)<1) {
		$ti = Title::newFromText($texFavorites);
		$ac = new Article($ti);
		if ($ac->exists()) {
			$tf = $ac->getContent();
			
			$tf = explode("\n", $tf);
			
			if (is_array($tf)) {
					foreach	($tf as $favorite) {
						if (preg_match("/^\|([^\-\}].*)/", $favorite, $a) ) $texList[] = explode("||", $a[1]);
					}
			}
		}
	}
	
	
	// register some defaut values
	
	if (count($texList)<1) {
		$texList[] = array("\alpha", "\alpha");
		$texList[] = array("\beta", "\beta");
		$texList[] = array("\gamma", "\gamma");
		$texList[] = array("\delta", "\delta");
		$texList[] = array("***","***");	
		$texList[] = array("\sin", "\sin (x)");
		$texList[] = array("\cos", "\cos (x)");	
		$texList[] = array("\tan", "\tan (x)");
		$texList[] = array("\lim", "\lim_{x\rightarrow\infty} f(x)");		
		$texList[] = array("***","***");	
		$texList[] = array("\approx", "\approx");
		$texList[] = array("=", "=");	
		$texList[] = array("***","***");
		$texList[] = array("\textstyle \frac{a}{b}", "\frac{a}{b}");
		$texList[] = array("\textstyle \int_a^b", "\int_a^b f(x)\,dx");
		$texList[] = array("\textstyle \sum", "\sum_{a=1}^b");
		$texList[] = array("\textstyle \prod_a^b", "\prod_{a=1}^b");
	}
	
	$sc[] = array("\t", "\\t", "&#92;&#92;t");
	$sc[] = array("\n", "\\n", "&#92;&#92;n");
	$sc[] = array("\r", "\\r", "&#92;&#92;r");
	$sc[] = array("\f", "\\f", "&#92;&#92;f");
	$sc[] = array("\l", "\\l", "&#92;&#92;l");	
	$sc[] = array("\a", "\\a", "&#92;&#92;a");	
	
	$il = "<ul><li>";
	foreach($texList as $item) {
	
		foreach($sc as $c) {
			$item[0] = trim(str_replace($c[0], $c[1], $item[0]));
			$item[1] = trim(str_replace($c[0], $c[2], $item[1]));
		}
		
		$item[1] = str_replace("\\", "&#92;&#92;", $item[1]);
	
		if ($item[0] != "***") $ico = $wgOut->parse("<math>".trim($item[0])."</math>");
		
		$ico = preg_replace("/<\/p.*?>/i", "", $ico);
		$ico = preg_replace("/alt=[\'\"]{1}[^\'\"]*[\'\"]{1}/i", "", $ico);
		$ico = preg_replace("/class=[\'\"][^\'\"]*[\'\"]/i", "", $ico);	
		$ico = preg_replace("/.*<img ([^>]+>).*/i", "<img alt=\"click for inserting\" class=\"boxButton\" onclick=\"texFavoritInsert('".$item[1]."')\" \\1", $ico);
		
		if ($item[0] == "***") $il = $il . "</li><li>"; else $il = $il." ".$ico;
	}
	$il = $il . "</li></ul>";
	
	$texextra = "";
	$popup = "";
	if ($modus == "tex") {
		$texextra = <<<END
				&nbsp;&nbsp;
				<span class="boxButton" onclick="texInsert()">&nbsp;Insert&nbsp;</span>
				&nbsp;&nbsp;
				<span class="boxButton" onclick="texClose()">&nbsp;Close&nbsp;</span>
END;
		$popup = "<h3>Popup Window: The T<sub>E</sub>X Box</h3>";
	}




	$wgOut->addScript(<<<END
<style type="text/css"> .boxButton { vertical-align: bottom; margin: 2px; padding: 0; background-color: #DFDFDF; cursor: pointer; } span.boxButton:hover {background-color: #0099FF} body { font: x-small sans-serif; background: #f9f9f9; color: black; margin: 0; padding: 0; } </style>
END
);

/*

*/
	$wgOut->addScript(<<<END
<script type="text/javascript">
// ajaxs function copied from ajax.js

// ajaxs function copied from ajax.js

function texSetResult(request)
{
	if ( request.status != 200 ) {
		alert("Error: " + request.status + " " + request.statusText + ": " + request.responseText);
		return;
	}
	
	var result = request.responseText;

	//alert("result "+result);

	if (result.substr(0,1)==":") result = result.substr(1, result.length-1);

	pat = /<input[^>]*hidden[^>]*wfSajaxMath[^>]*>/
	if (!result.match(pat)) result = "ajax request error.";

	t = document.getElementById("texImg");
	if ( t == null ) {
		oldbody=body.innerHTML;
		body.innerHTML= '<div id="texImgContainer"><div id="texImg" ></div></div>' ;
		t = document.getElementById("texImg");
	}
	t.innerHTML = "&nbsp;&nbsp;"+result;
	t.style.display='block';

}

var memory;

// This will call the php function that will eventually
// return a results table
function texPreview()
{
	var x;

	x = document.getElementById("wpTextbox1").value;
	//alert(x);	

	// the plus must be escaped in the url
	pat = /\+/g
	x = x.replace(pat, "plus924386");

	// Don't search again if the query is the same
	if (x==memory) return;

	memory=x;

	//if (x != "") x_wfSajaxMath(x, texSetResult);
	if (x != "") sajax_do_call( "wfSajaxMath", [ x ], texSetResult );
}



window.onload = function() {
	//alert("on load ...");

	body = document.getElementById("texImg");
}


function texInsert () {
	x = document.getElementById("wpTextbox1").value;
	var main = window.opener.document;
	if (main && !main.closed) insertTags("<math>", "</math>", x, main);
}

function texClear () { 
	document.getElementById("wpTextbox1").value = "";
}


function texFavoritInsert (tex) {

	var main = window.document;
	insertTags("", " ", tex, main);
	texPreview();
}


function texClose() { 
    window.close();
    return true ;
}





// copied form wikibits.js
// added obj to function parameters

// apply tagOpen/tagClose to selection in textarea,
// use sampleText instead of selection if there is none
// copied and adapted from phpBB
function insertTags(tagOpen, tagClose, sampleText, obj) {
	if (obj.editform)
		var txtarea = obj.editform.wpTextbox1; 
	else {
		// some alternate form? take the first one we can find
		var areas = obj.getElementsByTagName('textarea');
		var txtarea = areas[0];
	}

	// IE
	if (obj.selection  && !is_gecko) {
		var theSelection = obj.selection.createRange().text;
		if (!theSelection)
			theSelection=sampleText;
		txtarea.focus();
		if (theSelection.charAt(theSelection.length - 1) == " ") { // exclude ending space char, if any
			theSelection = theSelection.substring(0, theSelection.length - 1);
			obj.selection.createRange().text = tagOpen + theSelection + tagClose + " ";
		} else {
			obj.selection.createRange().text = tagOpen + theSelection + tagClose;
		}

	// Mozilla
	} else if(txtarea.selectionStart || txtarea.selectionStart == '0') {
		var replaced = false;
		var startPos = txtarea.selectionStart;
		var endPos = txtarea.selectionEnd;
		if (endPos-startPos)
			replaced = true;
		var scrollTop = txtarea.scrollTop;
		var myText = (txtarea.value).substring(startPos, endPos);
		if (!myText)
			myText=sampleText;
		if (myText.charAt(myText.length - 1) == " ") { // exclude ending space char, if any
			subst = tagOpen + myText.substring(0, (myText.length - 1)) + tagClose + " ";
		} else {
			subst = tagOpen + myText + tagClose;
		}
		txtarea.value = txtarea.value.substring(0, startPos) + subst +
			txtarea.value.substring(endPos, txtarea.value.length);
		txtarea.focus();
		//set new selection
		if (replaced) {
			var cPos = startPos+(tagOpen.length+myText.length+tagClose.length);
			//txtarea.selectionStart = cPos;
			//txtarea.selectionEnd = cPos;
		} else {
			//txtarea.selectionStart = startPos+tagOpen.length;
			//txtarea.selectionEnd = startPos+tagOpen.length+myText.length;
		}
		txtarea.scrollTop = scrollTop;

	// All other browsers get no toolbar.
	// There was previously support for a crippled "help"
	// bar, but that caused more problems than it solved.
	}
	// reposition cursor if possible
	if (txtarea.createTextRange)
		txtarea.caretPos = obj.selection.createRange().duplicate();
}
</script>
END
);




	if ($modus == "tex") { 
		$wgOut->addScript(<<<END
<script type="text/javascript"> function onLoadSpecialBox () { document.getElementById("globalWrapper").innerHTML = document.getElementById("texBoxWrapper").innerHTML ; }  addOnloadHook(onLoadSpecialBox); </script>
END
);
	}

	$wgOut->addHTML(<<<END
	<div id="texBoxWrapper" >
		<div id="texBox" style="padding: 1em; font: x-small sans-serif;">
			$popup
			<div id="texImg" style="border-style: solid; border-width: 1px; padding: 1em;"></div>
			<br/>
			<span >Enter a T<sub>E</sub>X expression:</span>
   			<br/>
			<textarea id="wpTextbox1" style="WIDTH: 100%;" rows="4" ></textarea>
			<br/>
			<div>
				<span class="boxButton" onclick="texPreview()">&nbsp;Preview&nbsp;</span>
				&nbsp;&nbsp;
				<span class="boxButton" onclick="texClear()">&nbsp;Clear&nbsp;</span>
				$texextra
			</div>
			<br/>
			<h5>T<sub>E</sub>X Favorites</h5>
			$il
			<div id="texFuncs"></div>
			<input id="searchInput" type="text" style="display: none;" ></input>
		</div>
	</div>
END
);
 
}





function wfSajaxMath( $term ) { 

	$term = str_replace("plus924386", "+", $term);
	$math = MathRenderer::renderMath($term);

	return "<input type=\"hidden\" name=\"wfSajaxMath\" >".$math;
	
}



# REGISTER HOOKS

$wgHooks['EditPage::showEditForm:initial'][] 	= 'wfAddTEXScript';
$wgHooks['SpecialPage_initList'][] 		= 'wfAddTEXSpecialPage'; 


function wfAddTEXSpecialPage($q){

	$sp = new SpecialPage("Texbox");
	SpecialPage::addPage($sp);

	return true;
}


function wfAddTEXScript ($q) { 

	global $wgOut;
	
	$ico = MathRenderer::renderMath("\\textstyle \sum"); 
	$ico = preg_replace("/alt=[\'\"]{1}[^\'\"]*[\'\"]{1}/i", "", $ico);
	$ico = preg_replace("/class=[\'\"][^\'\"]*[\'\"]/i", "", $ico);	
	$ico = preg_replace("/\n/i", "", $ico);
	$ico = preg_replace("/.*<img ([^>]+>).*/i", "<img style=\"background-color: #DFDFDF; cursor: pointer;\" alt=\"TEX Editor\" onclick=\"window.open(\'index.php?title=Special:Texbox\&box=tex\', \'TEX_Editor\', \'width=500\')\" \\1", $ico);	

	$wgOut->addScript("<script type=\"text/javascript\"> function onLoadTex () { var oDiv=document.getElementById(\"toolbar\"); oDiv.innerHTML = oDiv.innerHTML+"."'".$ico."'"."; } addOnloadHook(onLoadTex); </script>\n");

	return true;
}