Creating a PHP actionscript highlighter

Hey guys,
Before I begin, let me make clear that I know about syntax highlighters already in existance (like GeSHi). However, I want to create one (with your help :ne: ) that’s compact and built specifically for AS.

I borrowed the syntax from GeSHi:

<?php
$as=array(
	'COMMENT_SINGLE'=>array(1=>'//',2=>'#'),
	'QUOTEMARKS'=>array("'",'"'),
	'KEYWORDS'=>array(
		1=>array(
			'#include','for','foreach','if','elseif','else','while','do','dowhile',
			'endwhile','endif','switch','case','endswitch','return','break','continue','in'
			),
		2=>array('null','false','true','var','default','function','class','new','_global'),
		3=>array(
			'#endinitclip','#initclip','__proto__','_accProps','_alpha','_currentframe',
			'_droptarget','_focusrect','_framesloaded','_height','_highquality','_lockroot',
			'_name','_parent','_quality','_root','_rotation','_soundbuftime','_target','_totalframes',
			'_url','_visible','_width','_x','_xmouse','_xscale','_y','_ymouse','_yscale','abs',
			'Accessibility','acos','activityLevel','add','addListener','addPage','addProperty',
			'addRequestHeader','align','allowDomain','allowInsecureDomain','and','appendChild',
			'apply','Arguments','Array','asfunction','asin','atan','atan2','attachAudio','attachMovie',
			'attachSound','attachVideo','attributes','autosize','avHardwareDisable','background',
			'backgroundColor','BACKSPACE','bandwidth','beginFill','beginGradientFill','blockIndent',
			'bold','Boolean','border','borderColor','bottomScroll','bufferLength','bufferTime',
			'builtInItems','bullet','Button','bytesLoaded','bytesTotal','call','callee','caller',
			'Camera','capabilities','CAPSLOCK','caption','catch','ceil','charAt','charCodeAt',
			'childNodes','chr','clear','clearInterval','cloneNode','close','Color','concat',
			'connect','condenseWhite','constructor','contentType','ContextMenu','ContextMenuItem',
			'CONTROL','copy','cos','createElement','createEmptyMovieClip','createTextField',
			'createTextNode','currentFps','curveTo','CustomActions','customItems','data','Date',
			'deblocking','delete','DELETEKEY','docTypeDecl','domain','DOWN',
			'duplicateMovieClip','duration','dynamic','E','embedFonts','enabled',
			'END','endFill','ENTER','eq','Error','ESCAPE','escape','eval',
			'exactSettings','exp','extends','finally','findText','firstChild','floor',
			'flush','focusEnabled','font','fps','fromCharCode','fscommand',
			'gain','ge','get','getAscii','getBeginIndex','getBounds','getBytesLoaded','getBytesTotal',
			'getCaretIndex','getCode','getCount','getDate','getDay','getDepth','getEndIndex','getFocus',
			'getFontList','getFullYear','getHours','getInstanceAtDepth','getLocal','getMilliseconds',
			'getMinutes','getMonth','getNewTextFormat','getNextHighestDepth','getPan','getProgress',
			'getProperty','getRGB','getSeconds','getSelected','getSelectedText','getSize','getStyle',
			'getStyleNames','getSWFVersion','getText','getTextExtent','getTextFormat','getTextSnapshot',
			'getTime','getTimer','getTimezoneOffset','getTransform','getURL','getUTCDate','getUTCDay',
			'getUTCFullYear','getUTCHours','getUTCMilliseconds','getUTCMinutes','getUTCMonth','getUTCSeconds',
			'getVersion','getVolume','getYear','globalToLocal','goto','gotoAndPlay','gotoAndStop',
			'hasAccessibility','hasAudio','hasAudioEncoder','hasChildNodes','hasEmbeddedVideo','hasMP3',
			'hasPrinting','hasScreenBroadcast','hasScreenPlayback','hasStreamingAudio','hasStreamingVideo',
			'hasVideoEncoder','height','hide','hideBuiltInItems','hitArea','hitTest','hitTestTextNearPos',
			'HOME','hscroll','html','htmlText','ID3','ifFrameLoaded','ignoreWhite','implements',
			'import','indent','index','indexOf','Infinity','-Infinity','INSERT','insertBefore','install',
			'instanceof','int','interface','isActive','isDebugger','isDown','isFinite','isNaN','isToggled',
			'italic','join','Key','language','lastChild','lastIndexOf','le','leading','LEFT','leftMargin',
			'length','level','lineStyle','lineTo','list','LN10','LN2','load','loadClip','loaded','loadMovie',
			'loadMovieNum','loadSound','loadVariables','loadVariablesNum','LoadVars','LocalConnection',
			'localFileReadDisable','localToGlobal','log','LOG10E','LOG2E','manufacturer','Math','max',
			'MAX_VALUE','maxChars','maxhscroll','maxscroll','mbchr','mblength','mbord','mbsubstring','menu',
			'message','Microphone','min','MIN_VALUE','MMExecute','motionLevel','motionTimeOut','Mouse',
			'mouseWheelEnabled','moveTo','Movieclip','MovieClipLoader','multiline','muted','name','names','NaN',
			'ne','NEGATIVE_INFINITY','NetConnection','NetStream','newline','nextFrame',
			'nextScene','nextSibling','nodeName','nodeType','nodeValue','not','Number','Object',
			'on','onActivity','onChanged','onClipEvent','onClose','onConnect','onData','onDragOut',
			'onDragOver','onEnterFrame','onID3','onKeyDown','onKeyUp','onKillFocus','onLoad','onLoadComplete',
			'onLoadError','onLoadInit','onLoadProgress','onLoadStart','onMouseDown','onMouseMove','onMouseUp',
			'onMouseWheel','onPress','onRelease','onReleaseOutside','onResize','onRollOut','onRollOver',
			'onScroller','onSelect','onSetFocus','onSoundComplete','onStatus','onUnload','onUpdate','onXML',
			'or(logischesOR)','ord','os','parentNode','parseCSS','parseFloat','parseInt','parseXML','password',
			'pause','PGDN','PGUP','PI','pixelAspectRatio','play','playerType','pop','position',
			'POSITIVE_INFINITY','pow','prevFrame','previousSibling','prevScene','print','printAsBitmap',
			'printAsBitmapNum','PrintJob','printNum','private','prototype','public','push','quality',
			'random','rate','registerClass','removeListener','removeMovieClip','removeNode','removeTextField',
			'replaceSel','replaceText','resolutionX','resolutionY','restrict','reverse','RIGHT',
			'rightMargin','round','scaleMode','screenColor','screenDPI','screenResolutionX','screenResolutionY',
			'scroll','seek','selectable','Selection','send','sendAndLoad','separatorBefore','serverString',
			'set','setvariable','setBufferTime','setClipboard','setDate','setFocus','setFullYear','setGain',
			'setHours','setInterval','setMask','setMilliseconds','setMinutes','setMode','setMonth',
			'setMotionLevel','setNewTextFormat','setPan','setProperty','setQuality','setRate','setRGB',
			'setSeconds','setSelectColor','setSelected','setSelection','setSilenceLevel','setStyle',
			'setTextFormat','setTime','setTransform','setUseEchoSuppression','setUTCDate','setUTCFullYear',
			'setUTCHours','setUTCMilliseconds','setUTCMinutes','setUTCMonth','setUTCSeconds','setVolume',
			'setYear','SharedObject','SHIFT','shift','show','showMenu','showSettings',
			'silenceLevel','silenceTimeout','sin','size','slice','smoothing','sort','sortOn','Sound','SPACE',
			'splice','split','sqrt','SQRT1_2','SQRT2','Stage','start','startDrag','static','status','stop',
			'stopAllSounds','stopDrag','String','StyleSheet','styleSheet','substr',
			'substring','super','swapDepths','System','TAB','tabChildren','tabEnabled','tabIndex',
			'tabStops','tan','target','targetPath','tellTarget','text','textColor','TextField','TextFormat',
			'textHeight','TextSnapshot','textWidth','this','throw','time','toggleHighQuality','toLowerCase',
			'toString','toUpperCase','trace','trackAsMenu','try','type','typeof','undefined',
			'underline','unescape','uninstall','unloadClip','unloadMovie','unLoadMovieNum','unshift','unwatch',
			'UP','updateAfterEvent','updateProperties','url','useCodePage','useEchoSuppression','useHandCursor',
			'UTC','valueOf','variable','version','Video','visible','void','watch','width',
			'with','wordwrap','XML','xmlDecl','XMLNode','XMLSocket'
			)
		),
	'SYMBOLS'=>array('(',')','[',']','{','}','!','@','%','&','*','|','/','<','>'),
	'STYLES'=>array(
		'KEYWORDS'=>array(
			1=>'color:#b1b100;',
			2=>'color:#000000;font-weight:bold;',
			3=>'color:#0066CC;'
			),
		'COMMENTS'=>'color:#808080;font-style:italic;',
		'STRINGS'=>'color:#ff0000;',
		'NUMBERS'=>'color:#cc66cc;',
		'SYMBOLS'=>'color:#66cc66;'
		),
);

and I started building it, but with no real direction.

Here’s what I have so far (directly underneath the first code example in the same file):

$str = "/*----- some comment*/
function arg(hey) {
    if(stuff == 4) {
        trace('hi');
    }
    //nice!
    trace('hello world');
    return stuff;
}";

$str = str_replace(" ","&nbsp;",$str);

# single-line comments
$str = preg_replace_callback("#//([\S\s]*)?\r#U", "doFormat", $str);

# multi-line comments
$str = preg_replace_callback("#/\*([\S\s]*)?\*/#U", "doFormat", $str);

# quotes

# keywords
for($i=0; $i<count($as['KEYWORDS'][1]); $i++) {
    $who = $as['KEYWORDS'][1][$i];
    $new = "<font style='{".$as['STYLES']['KEYWORDS'][1]."}'><a href='wiki.php?id=".strtolower($who)."'>".$who."</a></font>";
    $str = str_replace($who,$new,$str);
}

for($i=0; $i<count($as['KEYWORDS'][1]); $i++) {
    $who = $as['KEYWORDS'][2][$i];
    $new = "<font style='{".$as['STYLES']['KEYWORDS'][2]."}'><a href='wiki.php?id=".strtolower($who)."'>".$who."</a></font>";
    $str = str_replace($who,$new,$str);
}

# symbols

# function doFormat
function doFormat($m) {
    global $as;
    $code = "<font style='{".$as['STYLES']['COMMENTS']."}'>".$m[0]."</font>";
    return $code;
}

# function doCode
function doCode($m) {
    $swap = '';
    for ($i=0; $i < strlen($m[1]); $i++) {
        $swap .= '&#'.ord($m[1]{$i}).';';
    }
    return $swap;
}

# replace all newlines with breaks
$str = str_replace("\r","<br />",$str);
echo $str;
?>

</body>
</html>

Does anyone have any tips on how to get this thing working? If nothing else, it’s a good PHP-learning experience :nerd: