<?
/* This software is licensed through a BSD-style License.
 * http://www.opensource.org/licenses/bsd-license.php

Copyright (c) 2003, 2004, Jacob D. Cohen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
Neither the name of Jacob D. Cohen nor the names of his contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

/*

Special thanks to E.J. Brocklesby for providing PL/I language support.
Special thanks to F.R. for the XML language support.

*/

function keyword_replace($keywords$text$ncs false)
{
    
$cm = ($ncs)? "i" "";
    foreach (
$keywords as $keyword)
    {
        
$search[]  = "/(\\b$keyword\\b)/" $cm;
        
$replace[] = '<span class="keyword">\\0</span>';
    }

    
$search[]  = "/(\\bclass\s)/";
    
$replace[] = '<span class="keyword">\\0</span>';

    return 
preg_replace($search$replace$text);
}


function 
preproc_replace($preproc$text)
{
    foreach (
$preproc as $proc)
    {
        
$search[] = "/(\\s*#\s*$proc\\b)/";
        
$replace[] = '<span class="keyword">\\0</span>';
    }

    return 
preg_replace($search$replace$text);
}


function 
sch_syntax_helper($text)
{
    return 
$text;
}


function 
syntax_highlight_helper($text$language)
{
    
$preproc = array();
    
$preproc["C++"] = array(
    
"if",    "ifdef",   "ifndef""elif",  "else",
    
"endif""include""define""undef""line",
    
"error""pragma");
    
$preproc["C89"] = & $preproc["C++"];
    
$preproc["C"] = & $preproc["C89"];

    
$keywords = array(
    
"C++" => array(
    
"asm",          "auto",      "bool",     "break",            "case",
    
"catch",        "char",      /*class*/   "const",            "const_cast",
    
"continue",     "default",   "delete",   "do",               "double",
    
"dynamic_cast""else",      "enum",     "explicit",         "export",
    
"extern",       "false",     "float",    "for",              "friend",
    
"goto",         "if",        "inline",   "int",              "long",
    
"mutable",      "namespace""new",      "operator",         "private",
    
"protected",    "public",    "register""reinterpret_cast""return",
    
"short",        "signed",    "sizeof",   "static",           "static_cast",
    
"struct",       "switch",    "template""this",             "throw"
    
"true",         "try",       "typedef",  "typeid",           "typename",
    
"union",        "unsigned",  "using",    "virtual",          "void",
    
"volatile",     "wchar_t",   "while"),

    
"C89" => array(
    
"auto",     "break",    "case",     "char",     "const",
    
"continue""default",  "do",       "double",   "else",
    
"enum",     "extern",   "float",    "for",      "goto",
    
"if",       "int",      "long",     "register""return",
    
"short",    "signed",   "sizeof",   "static",   "struct",
    
"switch",   "typedef",  "union",    "unsigned""void",
    
"volatile""while"),

    
"C" => array(
    
"auto",     "break",    "case",     "char",     "const",
    
"continue""default",  "do",       "double",   "else",
    
"enum",     "extern",   "float",    "for",      "goto",
    
"if",       "int",      "long",     "register""return",
    
"short",    "signed",   "sizeof",   "static",   "struct",
    
"switch",   "typedef",  "union",    "unsigned""void",
    
"volatile""while",    "__restrict","_Bool"),

    
"PHP" => array(
    
"and",          "or",           "xor",      "__FILE__",     "__LINE__",
    
"array",        "as",           "break",    "case",         "cfunction",
    
/*class*/       "const",        "continue""declare",      "default",
    
"die",          "do",           "echo",     "else",         "elseif",
    
"empty",        "enddeclare",   "endfor",   "endforeach",   "endif",
    
"endswitch",    "endwhile",     "eval",     "exit",         "extends",
    
"for",          "foreach",      "function""global",       "if",
    
"include",      "include_once""isset",    "list",         "new",
    
"old_function""print",        "require",  "require_once""return",
    
"static",       "switch",       "unset",    "use",          "var",
    
"while",        "__FUNCTION__""__CLASS__"),

    
"Perl" => array(
    
"-A",           "-B",           "-C",       "-M",           "-O",
    
"-R",           "-S",           "-T",       "-W",           "-X",
    
"-b",           "-c",           "-d",       "-e",           "-f",
    
"-g",           "-k",           "-l",       "-o",           "-p",
    
"-r",           "-s",           "-t",       "-u",           "-w",
    
"-x",           "-z",           "ARGV",     "DATA",         "ENV",
    
"SIG",          "STDERR",       "STDIN",    "STDOUT",       "atan2",
    
"bind",         "binmode",      "bless",    "caller",       "chdir",
    
"chmod",        "chomp",        "chop",     "chown",        "chr",
    
"chroot",       "close",        "closedir""cmp",          "connect",
    
"continue",     "cos",          "crypt",    "dbmclose",     "dbmopen",
    
"defined",      "delete",       "die",      "do",           "dump",
    
"each",         "else",         "elsif",    "endgrent",     "endhostent",
    
"endnetent",    "endprotent",   "endpwent""endservent",   "eof",
    
"eq",           "eval",         "exec",     "exists",       "exit",
    
"exp",          "fcntl",        "fileno",   "flock",        "for",
    
"foreach",      "fork",         "format",   "formline",     "ge",
    
"getc",         "getgrent",     "getgrid",  "getgrnam",     "gethostbyaddr",
    
"gethostbyname","gethostent",   "getlogin""getnetbyaddr""getnetbyname",
    
"getnetent",    "getpeername",  "getpgrp",  "getppid",      "getpriority",
    
"getprotobyname","getprotobynumber","getprotoent","getpwent","getpwnam",
    
"getpwuid",     "getservbyname","getservbyport","getservent","getsockname",
    
"getsockopt",   "glob",         "gmtime",   "goto",         "grep",
    
/*gt*/          "hex",          "if",       "import",       "index",
    
"int",          "ioctl",        "join",     "keys",         "kill",
    
"last",         "lc",           "lcfirst",  "le",           "length",
    
"link",         "listen",       "local",    "localtime",    "log",
    
"lstat",        /*lt*/          "m",        "map",          "mkdir",
    
"msgctl",       "msgget",       "msgrcv",   "msgsnd",       "my",
    
"ne",           "next",         "no",       "oct",          "open",
    
"opendir",      "ord",          "pack",     "package",      "pipe",
    
"pop",          "pos",          "print",    "printf",       "push",
    
"q",            "qq",           "quotemeta","qw",           "qx",
    
"rand",         "read",         "readdir",  "readlink",     "recv",
    
"redo",         "ref",          "refname",  "require",      "reset",
    
"return",       "reverse",      "rewinddir","rindex",       "rmdir",
    
"s",            "scalar",       "seek",     "seekdir",      "select",
    
"semctl",       "semget",       "semop",    "send",         "setgrent",
    
"sethostent",   "setnetent",    "setpgrp",  "setpriority",  "setprotoent",
    
"setpwent",     "setservent",   "setsockopt","shift",       "shmctl",
    
"shmget",       "shmread",      "shmwrite""shutdown",     "sin",
    
"sleep",        "socket",       "socketpair","sort",        "splice",
    
"split",        "sprintf",      "sqrt",     "srand",        "stat",
    
"study",        "sub",          "substr",   "symlink",      "syscall",
    
"sysopen",      "sysread",      "system",   "syswrite",     "tell",
    
"telldir",      "tie",          "tied",     "time",         "times",
    
"tr",           "truncate",     "uc",       "ucfirst",      "umask",
    
"undef",        "unless",       "unlink",   "unpack",       "unshift",
    
"untie",        "until",        "use",      "utime",        "values",
    
"vec",          "wait",         "waitpid",  "wantarray",    "warn"
    
"while",        "write",        "y",        "or",           "and",
    
"not"),

    
"Java" => array(
    
"abstract",     "boolean",      "break",    "byte",         "case",
    
"catch",        "char",         /*class*/   "const",        "continue",
    
"default",      "do",           "double",   "else",         "extends",
    
"final",        "finally",      "float",    "for",          "goto",
    
"if",           "implements",   "import",   "instanceof",   "int",
    
"interface",    "long",         "native",   "new",          "package",
    
"private",      "protected",    "public",   "return",       "short",
    
"static",       "strictfp",     "super",    "switch",       "synchronized",
    
"this",         "throw",        "throws",   "transient",    "try",
    
"void",         "volatile",     "while"),

    
"VB" => array(
    
"AddressOf",    "Alias",        "And",      "Any",          "As",
    
"Binary",       "Boolean",      "ByRef",    "Byte",         "ByVal",
    
"Call",         "Case",         "CBool",    "CByte",        "CCur",
    
"CDate",        "CDbl",         "CInt",     "CLng",         "Close",
    
"Const",        "CSng",         "CStr",     "Currency",     "CVar",
    
"CVErr",        "Date",         "Debug",    "Declare",      "DefBool",
    
"DefByte",      "DefCur",       "DefDate",  "DefDbl",       "DefInt",
    
"DefLng",       "DefObj",       "DefSng",   "DefStr",       "DefVar",
    
"Dim",          "Do",           "Double",   "Each",         "Else",
    
"End",          "Enum",         "Eqv",      "Erase",        "Error",
    
"Event",        "Exit",         "For",      "Friend",       "Function",
    
"Get",          "Get",          "Global",   "GoSub",        "GoTo",
    
"If",           "Imp",          "Implements","In",          "Input",
    
"Integer",      "Is",           "LBound",   "Len",          "Let",
    
"Lib",          "Like",         "Line",     "Lock",         "Long",
    
"Loop",         "LSet",         "Mod",      "Name",         "Next",
    
"Not",          "Nothing",      "Null",     "Object",       "On",
    
"Open",         "Option Base 1","Option Compare Binary",
    
"Option Compare Database""Option Compare Text""Option Explicit",
    
"Option Private Module""Optional",        "Or",           "Output",
    
"ParamArray",   "Preserve",     "Print",    "Private",      "Property",
    
"Public",       "Put",          "RaiseEvent","Random",      "Read",
    
"ReDim",        "Resume",       "Return",   "RSet",         "Seek",
    
"Select",       "Set",          "Single",   "Spc",          "Static",
    
"Step",         "Stop",         "String",   "Sub",          "Tab",
    
"Then",         "To",           "Type",     "UBound",       "Unlock",
    
"Variant",      "Wend",         "While",    "With",         "WithEvents",
    
"Write",        "Xor"),

    
"C#" => array(
    
"abstract",     "as",           "base",     "bool",         "break",
    
"byte",         "case",         "catch",    "char",         "checked",
    
/*class*/       "const",        "continue""decimal",      "default",
    
"delegate",     "do",           "double",   "else",         "enum",
    
"event",        "explicit",     "extern",   "false",        "finally",
    
"fixed",        "float",        "for",      "foreach",      "goto",
    
"if",           "implicit",     "in",       "int",          "interface",
    
"internal",     "is",           "lock",     "long",         "namespace",
    
"new",          "null",         "object",   "operator",     "out",
    
"override",     "params",       "private",  "protected",    "public",
    
"readonly",     "ref",          "return",   "sbyte",        "sealed",
    
"short",        "sizeof",       "stackalloc","static",      "string",
    
"struct",       "switch",       "this",     "throw",        "true",
    
"try",          "typeof",       "uint",     "ulong",        "unchecked",
    
"unsafe",       "ushort",       "using",    "virtual",      "volatile",
    
"void",         "while"),
    
    
"Ruby" => array(
    
"alias",        "and",          "begin",    "break",        "case",
    
/*class*/       "def",          "defined",  "do",           "else",
    
"elsif",        "end",          "ensure",   "false",        "for",
    
"if",           "in",           "module",   "next",         "module",
    
"next",         "nil",          "not",      "or",           "redo",
    
"rescue",       "retry",        "return",   "self",         "super",
    
"then",         "true",         "undef",    "unless",       "until",
    
"when",         "while",        "yield"),

    
"Python" => array(
    
"and",          "assert",       "break",    /*"class",*/    "continue",
    
"def",          "del",          "elif",     "else",         "except",
    
"exec",         "finally",      "for",      "from",         "global",
    
"if",           "import",       "in",       "is",           "lambda",
    
"not",          "or",           "pass",     "print",        "raise",
    
"return",       "try",          "while",    "yield"),

    
"Pascal" => array(
    
"Absolute",     "Abstract",     "All",      "And",          "And_then",
    
"Array",        "Asm",          "Begin",    "Bindable",     "Case",
    
/*"Class",*/    "Const",        "Constructor","Destructor""Div",
    
"Do",           "Downto",       "Else",     "End",          "Export",
    
"File",         "For",          "Function""Goto",         "If",
    
"Import",       "Implementation","Inherited","In",          "Inline",
    
"Interface",    "Is",           "Label",    "Mod",          "Module",
    
"Nil",          "Not",          "Object",   "Of",           "Only",
    
"Operator",     "Or",           "Or_else",  "Otherwise",    "Packed",
    
"Pow",          "Procedure",    "Program",  "Property",     "Protected",
    
"Qualified",    "Record",       "Repeat",   "Restricted",   "Set",
    
"Shl",          "Shr",          "Then",     "To",           "Type",
    
"Unit",         "Until",        "Uses",     "Value",        "Var",
    
"View",         "Virtual",      "While",    "With",         "Xor"),

    
"mIRC" => array(
        ),

    
"PL/I" => array(
    
"A",            "ABS",            "ACOS",        "%ACTIVATE",    "ACTUALCOUNT"
    
"ADD",            "ADDR",            "ADDREL",    "ALIGNED",        "ALLOCATE"
    
"ALLOC",        "ALLOCATION",    "ALLOCN",    "ANY",            "ANYCONDITION"
    
"APPEND",        "AREA",            "ASIN",        "ATAN",            "ATAND"
    
"ATANH",        "AUTOMATIC",    "AUTO",        "B",            "B1"
    
"B2",            "B3",            "B4",        "BACKUP_DATE",    "BASED"
    
"BATCH",        "BEGIN",        "BINARY",    "BIN",            "BIT",
    
"BLOCK_BOUNDARY_FORMAT",        "BLOCK_IO",    "BLOCK_SIZE",    "BOOL",
    
"BUCKET_SIZE",    "BUILTIN",        "BY",        "BYTE",            "BYTESIZE",
    
"CALL",            "CANCEL_CONTROL_O",            "CARRIAGE_RETURN_FORMAT",
    
"CEIL",            "CHAR""CHARACTER",    "CLOSE",    "COLLATE",        "COLUMN",
    
"CONDITION",    "CONTIGUOUS",    "CONTIGUOUS_BEST_TRY",        "CONTROLLED",
    
"CONVERSION",    "COPY",            "COS",        "COSD",            "COSH",
    
"CREATION_DATE",                "CURRENT_POSITION",            "DATE",
    
"DATETIME",        "%DEACTIVATE",    "DECIMAL",    "DEC",            "%DECLARE",
    
"%DCL",            "DECLARE",        "DCL",        "DECODE",        "DEFAULT_FILE_NAME",
    
"DEFERRED_WRITE",                "DEFINED",    "DEF",            "DELETE",
    
"DESCRIPTOR",    "%DICTIONARY",    "DIMENSION","DIM",           "DIRECT",
    
"DISPLAY",        "DIVIDE",        "%DO",        "DO",            "E",
    
"EDIT",            "%ELSE",        "ELSE",        "EMPTY",        "ENCODE",
    
"%END",            "END",            "ENDFILE",    "ENDPAGE",        "ENTRY",
    
"ENVIRONMENT",    "ENV",            "%ERROR",    "ERROR",        "EVERY",
    
"EXP",            "EXPIRATION_DATE",            "EXTEND",        "EXTENSION_SIZE",
    
"EXTERNAL",        "EXT",            "F",        "FAST_DELETE",    "%FATAL",
    
"FILE",            "FILE_ID",        "FILE_ID_TO",                "FILE_SIZE",
    
"FINISH",        "FIXED",        "FIXEDOVERFLOW",            "FOFL",
    
"FIXED_CONTROL_FROM",            "FIXED_CONTROL_SIZE",        "FIXED_CONTROL_SIZE_TO",
    
"FIXED_CONTROL_TO",                "FIXED_LENGTH_RECORDS",        "FLOAT",
    
"FLOOR",        "FLUSH",        "FORMAT",    "FREE",            "FROM",
    
"GET",            "GLOBALDEF",    "GLOBALREF",                "%GOTO",
    
"GOTO",            "GO""TO",        "GROUP_PROTETION",            "HBOUND",
    
"HIGH",            "INDENT",        "%IF",        "IF",            "IGNORE_LINE_MARKS",
    
"IN",            "%INCLUDE",        "INDEX",    "INDEXED",        "INDEX_NUMBER",
    
"%INFORM",        "INFORM",        "INITIAL",    "INIT",            "INITIAL_FILL",
    
"INPUT",        "INT",            "INTERNAL",    "INTO",            "KEY",
    
"KEYED",        "KEYFROM",        "KEYTO",    "LABEL",        "LBOUND"