Version 1.0 (released Jan. 4, 2010)
Introduction
Use this script to convert your HTML textareas into a code editor with realtime syntax hilighting.
You can create as many editors as you want within your HTML page. When put into a form, the
contents can be submitted, e.g. to be written to a file.
Generally, code editing should work on Windows with Internet Explorer 5.5+ and with browsers
using the Mozilla 1.3+ engine, i.e. all browsers that support "designMode".
This script was tested with the following systems and browsers:
Windows XP/Vista:
IE 8 Opera 9 FF 3
If you use another browser or operating system, this script may not work for you - sorry.
NOTE: The script also works with browsers that don't support code editing - a simple textarea
will replace the code editor.
List of supported languages
Currently the code editor supports the following languages:
Known issues
This is a list of things that don't work at the moment. If somebody knows a solution, please
tell me! ;-)
The tab key does not work correctly with Opera browsers.
Tabs are converted into 4 entities when the code is "loaded", and 4
entities will be converted into a single tab character when the code is
"saved". Please note that this is just a workaround, since there is no HTML entity for tabs
(as far as I know) that works in the browser's design mode.
Browsers that use the WebKit engine (e.g. Google Chrome) are not supported at the moment.
If you want to test it, just modify line 62.
JavaScript example
PHP example
<?php
/**
* This code is part of the FileManager software (www.gerd-tentler.de/tools/filemanager), copyright by
* Gerd Tentler. Obtain permission before selling this code or hosting it on a commercial website or
* redistributing it over the Internet or in any other medium. In all cases copyright must remain intact.
*/
/**
* This class provides static methods for general use.
*/
class Tools {
/* PUBLIC STATIC METHODS *********************************************************************** */
/**
* clean local directory
*
* @param string $dir directory
* @param integer $time optional: modification timestamp
*/
function cleanDir($dir, $time = null) {
if($dp = @opendir($dir)) {
while(($file = @readdir($dp)) !== false) {
if($file != '.' && $file != '..') {
if(!$time || @filemtime("$dir/$file") < $time) {
if(is_dir("$dir/$file")) Tools::removeDir("$dir/$file");
else @unlink("$dir/$file");
}
}
}
@closedir($dp);
}
}
/**
* remove local directory tree
*
* @param string $dir directory
*/
function removeDir($dir) {
if($dp = @opendir($dir)) {
while(($file = @readdir($dp)) !== false) {
if($file != '.' && $file != '..') {
if(is_dir("$dir/$file")) Tools::removeDir("$dir/$file");
else @unlink("$dir/$file");
}
}
@closedir($dp);
@rmdir($dir);
}
}
/**
* get number of files in local directory
*
* @param string $dir directory
* @return integer
*/
function getFileCount($dir) {
$cnt = 0;
if($dp = @opendir($dir)) {
while(($file = @readdir($dp)) !== false) {
if($file != '.' && $file != '..') {
if(is_file("$dir/$file")) $cnt++;
}
}
@closedir($dp);
}
return $cnt;
}
/**
* read local file
*
* @param string $file file path
* @param string $encoding optional: character set, example: ISO-8859-1
* @return string $data file data
*/
function readLocalFile($file, $encoding = '') {
$data = '';
if($fp = @fopen($file, 'r')) {
$data = @fread($fp, @filesize($file));
@fclose($fp);
}
return ($encoding != '') ? Tools::utf8Decode($data, $encoding) : $data;
}
/**
* save local file
*
* @param string $path file path
* @param string $data file data
* @param string $encoding optional: character set, example: ISO-8859-1
* @return boolean
*/
function saveLocalFile($path, &$data, $encoding = '') {
$ok = false;
if($encoding != '') $data = Tools::utf8Decode($data, $encoding);
if($fp = @fopen($path, 'w')) {
$ok = @fwrite($fp, $data);
@fclose($fp);
}
return $ok;
}
/**
* check if string contains 3 or 4 byte characters (Chinese etc.);
* usually these characters have a bigger width than the characters
* of the Latin alphabet
*
* @param string $str the string
* @return boolean
*/
function containsBigChars($str) {
return preg_match('/[\xE0-\xF4][\x80-\xBF]{2,3}/', $str);
}
/**
* check if string contains UTF-8 characters
*
* @param string $str the string
* @return boolean
*/
function isUtf8($str) {
return preg_match('%(?:
[\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|\xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
|\xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
|\xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
|[\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
|\xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
)%x', $str);
}
/**
* decode string if it contains UTF-8 characters
*
* @param string $str the string
* @param string $encoding optional: character set, example: ISO-8859-1
* @return string decoded string
*/
function utf8Decode($str, $encoding = '') {
if(Tools::isUtf8($str) && $encoding != 'UTF-8') {
if(function_exists('iconv')) {
if($encoding == '') $encoding = 'ISO-8859-1';
$str = iconv('UTF-8', "$encoding//TRANSLIT", $str);
}
else $str = utf8_decode($str);
}
return $str;
}
/**
* print icon
*
* @param string $path image path
* @param integer $width image width (pixels)
* @param integer $height image height (pixels)
* @param string $action optional: JavaScript action
* @param string $tooltip optional: tooltip
* @param string $style optional: CSS styles
*/
function printIcon($path, $width, $height, $action = '', $tooltip = '', $style = '') {
print "<img src=\"$path\" border=\"0\" width=\"$width\" height=\"$height\"";
if($action) print " onClick=\"$action\"";
if($tooltip) print " alt=\"$tooltip\" title=\"$tooltip\"";
if($style) print " style=\"$style\"";
print "/>\n";
}
/**
* strlen() that works also with UTF-8 strings
*
* @param string $str the string
* @param string $encoding optional: encoding
* @return integer number of characters
*/
function strlen($str, $encoding = '') {
if($encoding == 'UTF-8') {
if(function_exists('mb_strlen')) {
return mb_strlen($str, $encoding);
}
return preg_match_all('/.{1}/us', $str, $m);
}
return strlen($str);
}
/**
* substr() that works also with UTF-8 strings
*
* @param string $str the string
* @param integer $start start position
* @param integer $length optional: number of characters
* @param string $encoding optional: encoding
* @return string the substring
*/
function substr($str, $start, $length = null, $encoding = '') {
if($encoding == 'UTF-8') {
if(function_exists('mb_substr')) {
return mb_substr($str, $start, $length, $encoding);
}
if(!$length) $length = Tools::strlen($str) - $start;
preg_match('/.{' . $start . '}(.{' . $length . '})/us', $str, $m);
return $m[1];
}
return substr($str, $start, $length);
}
/**
* basename() that works also with UTF-8 strings
*
* @param string $path file path
* @param string $encoding optional: encoding
* @return string
*/
function basename($path, $encoding = '') {
if($encoding == 'UTF-8') {
return end(explode('/', $path));
}
return basename($path);
}
/**
* dirname() that works also with UTF-8 strings
*
* @param string $path file path
* @param string $encoding optional: encoding
* @return string
*/
function dirname($path, $encoding = '') {
if($encoding == 'UTF-8') {
$parts = explode('/', $path);
array_pop($parts);
return join('/', $parts);
}
return dirname($path);
}
/**
* convert strings like "8M" or "50K" to bytes
*
* @param string $str
* @return integer
*/
function toBytes($str) {
switch(strtoupper($str[strlen($str) - 1])) {
case 'M': return (int) $str * 1024 * 1024;
case 'K': return (int) $str * 1024;
case 'G': return (int) $str * 1024 * 1024 * 1024;
}
return (int) $str;
}
/**
* get microseconds - mimics PHP 5 microtime(true)
*
* @return float
*/
function microtime() {
list($usec, $sec) = explode(' ', microtime());
return (float) $usec + (float) $sec;
}
}
?>