mIRC syntax highlighting (javascript - highlight.js)


#1

WIP - Work in progress

See: https://github.com/isagalaev/highlight.js/issues/704

/*
Language: mIRC
Category: scripting
*/
function(hljs) {
	var ALIAS = {
		className: 'subst',
		variants: [
			{
				begin: /^alias (-l )?.+ \{/,
				end: /\}/
			},
			{
				begin: /^alias (-l )?.+/,
				end: /\n/
			}
		]
	};
	var MENU = {
		className: 'subst',
		variants: [
			{
				begin: /^menu .+ \{/,
				end: /\}/
			}
		]
	};
	var MENU_SUBST1 = {
		className: 'subst',
		begin: /\./,
		end: /:/,
		returnEnd: true
	};
	var MENU_SUBST2 = {
		className: 'subst',
		begin: /:/,
		end: /\n/,
		returnBegin: true
	};
	var DIALOG = {
		className: 'subst',
		variants: [
			{
				begin: /^dialog .+ \{/,
				end: /\}/
			}
		]
	};
	var ON = {
		className: 'subst',
		variants: [
			{
				begin: /^(on|ctcp|raw).+\{/,
				end: /\}/
			},
			{
				begin: /^(on|ctcp|raw).+:/,
				end: /\n/
			}
		]
	};
	var CODE_BLOCK = {
		className: 'subst',
		begin: /\{/,
		end: /\}/
	};
	var PAREN_BLOCK = {
		className: 'subst',
		begin: /\(/,
		end: /\)/
	};
	var LITERAL = {
		className: 'literal',
		begin: /\$(null|false|true)/
	};
	var VARIABLES = {
		className: 'variable',
		begin: /\%:?[\w\.\-<>=]*/
	};
	var IDENTIFIERS = {
		className: 'built_in',
		begin: /\$+(\d+-?|\+|yes|xor|wrap|window|wildtokcs|wildtok|wildsite|width|wid|wavedir|vol|vnick|version|vcmdver|vcmdstat|vcmd|vc|var|v2|v1|utfencode|utfdecode|usermode|url|uptime|upper|unsafe|ulist|ulevel|trust|true|treebar|totp|topic|toolbar|token|titlebar|tips|tip|timezone|timestampfmt|timestamp|timer|timeout|time|ticks|tempfn|target|tanh|tan|sysdir|switchbar|submenu|style|stripped|strip|str|status|starting|sslversion|sslready|ssllibdll|ssldll|sslcertsha256|sslcertsha1|ssl|sreq|sqrt|speak|sound|sorttokcs|sorttok|sockname|sockerr|sockbr|sock|snotify|snicks|snick|sline|site|sinh|sin|signal|show|shortfn|sha512|sha384|sha256|sha1|sfile|servertarget|serverip|server|send|sdir|scriptline|scriptdir|script|scon|scid|samepath|round|rnick|right|rgb|result|reptokcs|reptok|replacexcs|replacex|replacecs|replace|remtokcs|remtok|removecs|remove|remote|regsubex|regsub|regmlex|regml|regex|regerrstr|regbr|readn|readini|read|rawmsg|rawbytes|rand|raddress|r|query|qt|puttok|protect|prop|prefix|poscs|pos|portfree|portable|pnick|play|pic|pi|passivedcc|parseutf|parsetype|parseline|parms|os|ord|or|opnick|onpoly|onlinetotal|onlineserver|online|ok|nvnick|numtok|numeric|null|notify|notags|not|noqt|nopnick|nopath|nofile|no|nickmode|nick|nhnick|newnick|network|naddress|msgtags|msgstamp|msfile|mp3dir|mp3|mouse|modespl|modelast|modefirst|mode|mnick|mknickfn|mklogfn|mkfn|mircini|mircexe|mircdir|mididir|mid|menutype|menucontext|menubar|menu|me|md5|matchtokcs|matchtok|matchkey|mask|maddress|ltimer|lower|longip|longfn|logstampfmt|logstamp|logdir|log10|log|lof|locked|lock|link|lines|line|lf|level|len|leftwinwid|leftwincid|leftwin|left|lactivewid|lactivecid|lactive|knick|keyval|keyrpt|keychar|isutf|isupper|istok|islower|isid|isfile|isdir|isdde|isbit|isalias|iql|iptype|ip|inwho|inwave|intersect|int|instok|insong|inroundrect|inrect|input|inpoly|inpaste|inmp3|inmode|inmidi|initopic|ini|inellipse|iil|ignore|ifmatch2|ifmatch|iif|iel|idle|ibl|ialchan|ial|iaddress|hypot|hregex|hotp|hotlink|hotlinepos|hotline|host|hnick|hmatch|hmac|highlight|hget|hfind|hfile|height|hash|halted|group|gmt|gettok|getdot|getdir|get|fullscreen|fullname|fulldate|fulladdress|fserve|fserv|fromeditbox|fread|fopen|font|floor|fline|findtokcs|findtok|findfilen|findfile|finddirn|finddir|filtered|filename|file|fgetc|ferr|feof|false|exiting|exists|eventid|event|evalnext|eval|error|envvar|encode|emailaddr|email|editbox|ebeeps|duration|dqwindow|dname|dllcall|dll|dlevel|disk|dir|didwm|didtok|didreg|did|dialog|devent|deltok|decompress|decode|debug|ddename|dde|dccport|dccignore|dbuw|dbuh|daylight|day|date|ctrlenter|ctimer|ctime|crlf|creq|crc|cr|count|cosh|cos|comval|compress|compact|comerr|comchar|comchan|comcall|com|colour|color|cnick|cmdline|cmdbox|click|clevel|cid|chr|chat|chantypes|chanmodes|chan|ceil|cd|cb|cancel|caller|calc|bytes|bvar|bnick|bits|biton|bitoff|bindip|bfind|beta|base|banmask|banlist|awaytime|awaymsg|away|avoice|auto|atan2|atan|asin|asctime|asc|appstate|appactive|aop|ansi2mirc|anick|and|alias|agentver|agentstat|agentname|agent|addtokcs|addtok|address|adate|activewid|activecid|active|acos|abs|abook)/,
	};
	var KEYWORDS = {
		className: 'keyword',
		begin: /( (!?\.?!?\/?)|:)(xyzzy|writeini|write|winhelp|window|whois|while|wavplay|wallchops|vol|vcrem|vcmd|vcadd|var|uwho|username|url|updatenl|unsetall|unset|unload|ulist|treebar|tray|toolbar|tokenize|tnick|titlebar|tips|tip|timestamp|timer[\w\-\.]*|switchbar|strip|sreq|splay|speak|sound|sockwrite|sockudp|sockrename|sockread|sockpause|sockopen|sockmark|socklisten|socklist|sockclose|sockaccept|sline|signal|showmirc|setlayer|set|server|scon|scid|say|saveini|savebuf|save|ruser|run|rmdir|rline|rlevel|returnex|return|resetidle|reseterror|renwin|rename|remove|remote|remini|reload|registration|raw|quote|quit|queryrn|query|qmsg|qme|pvoice|proxy|protect|pop|playctrl|play|perform|pdcc|partall|part|parseline|onotice|omsg|notify|noop|msg|mode|mnick|mkdir|menubar|me|mdi|maxdepth|logview|log|localinfo|loadbuf|load|list|links|linesep|leave|join|iuser|inc|iline|ignore|if|identd|ialmark|ialclear|ial|hsave|hotlink|hop|hmake|hload|hinc|hfree|help|hdel|hdec|haltdef|halt|hadd|guser|gunload|gtalk|gstop|gsize|gshow|groups|gqreq|gpoint|gplay|goto|gopts|gmove|gload|ghide|fwrite|fupdate|fullname|fserve|fsend|fseek|fopen|font|fnord|flushini|flush|flood|flist|flash|firewall|finger|findtext|filter|fclose|exit|events|enable|emailaddr|elseif|else|editbox|echo|ebeeps|drawtext|drawsize|drawscroll|drawsave|drawrot|drawreplace|drawrect|drawpic|drawline|drawfill|drawdot|drawcopy|dqwindow|dns|dll|dline|dlevel|disconnect|disable|didtok|did|dialog|describe|dec|debug|ddeserver|dde|dccserver|dcc|ctcps|ctcpreply|ctcp|creq|copy|continue|comreg|comopen|commands|comlist|comclose|colour|color|cnick|closemsg|closefserves|closedccs|closechats|close|clipboard|cline|clearial|clearall|clear|channel|bwrite|bunset|btrunc|bset|breplace|break|bread|bindip|beep|bcopy|ban|background|away|avoice|autojoin|auto|auser|aop|anick|amsg|ame|aline|ajinvite|add|action|abook|nick)( |\n)/, 
	};
	var KEYWORDS2 = {
		className: 'keyword',
		begin: / !?(iswmcs|iswm|isvoice|isupper|isreg|isprotect|isop|ison|isnum|isnotify|islower|isletter|isinvite|isincs|isin|isignore|ishop|isexcept|ischan|isban|isavoice|isaop|isalpha|isalnum) /,
	};
	var M_COMMENT = hljs.inherit(
    	hljs.COMMENT(null, null),
    	{
      		variants: [
      		  /* single-line comment */
      		  { begin: /^\s*\;/, end: /\n/ },
      		  /* multi-line comment */
      		  { begin: /^\s*\/\*/, end: /\*\// }
     		],
   		}
  	);
	PAREN_BLOCK.contains = [LITERAL, IDENTIFIERS, VARIABLES, KEYWORDS2, hljs.NUMBER_MODE, 'self'];
	CODE_BLOCK.contains = [PAREN_BLOCK, M_COMMENT, IDENTIFIERS, VARIABLES, LITERAL, KEYWORDS, KEYWORDS2, hljs.NUMBER_MODE, 'self'];
  	ALIAS.contains = [M_COMMENT, IDENTIFIERS, LITERAL, VARIABLES, KEYWORDS, KEYWORDS2, hljs.NUMBER_MODE, PAREN_BLOCK, CODE_BLOCK];
  	DIALOG.contains = [hljs.NUMBER_MODE];
  	MENU.contains = [MENU_SUBST2, MENU_SUBST1, IDENTIFIERS, VARIABLES, hljs.NUMBER_MODE, PAREN_BLOCK];
  	MENU_SUBST1.contains = [IDENTIFIERS, VARIABLES, hljs.NUMBER_MODE, PAREN_BLOCK];
  	MENU_SUBST2.contains = [IDENTIFIERS, VARIABLES, KEYWORDS, hljs.NUMBER_MODE, PAREN_BLOCK, CODE_BLOCK];
  	ON.contains = [M_COMMENT, IDENTIFIERS, LITERAL, VARIABLES, KEYWORDS, KEYWORDS2, hljs.NUMBER_MODE, CODE_BLOCK];
  	return {
  		aliases: ['mrc'],
  		case_insensitive: true,
  		contains: [
			ALIAS,
			DIALOG,
			MENU,
			ON,
			M_COMMENT,
  		]
  	};
}

Syntax highlighting on this forum
#2

I’ve actually Pull Requested a mIRC.js definition file, see: https://github.com/highlightjs/highlight.js/pull/1788

However the travis build failed and I don’t know enough to correct it. I went ahead and performed the same travis build on my fork @GitHub which completed fine… :thinking:


#3

Here is my take on it:

/*
Language: mIRC Scripting Language
Category: scripting
*/
function(hljs) {
	var COMMENT_DOC = {
		className: 'comment',
		begin: /^\x20*\/\*\*\s+/,
		end: /\*\//,
		contains: [
			{
				className: 'doctag',
				begin: /@\w+/
			}
		]
	};

	var COMMENT_BLOCK = {
		className: 'comment',
		begin: /^\x20*\/\*/,
		end: /\*\//
	};

	var COMMENT_LINE = {
		className: 'comment',
		begin: /^\x20*;/,
		end: /$/
	};

	var STATEMENTS = {
		className: 'code',
		begin: /^(alias|dialog)(\x20+-l)?\x20+[^\x20]+/,
		returnBegin: true,
		contains: [
			{
				className: 'built_in',
				begin: /^(alias|dialog)\b/,
				contains: [
					{
						className: 'symbol',
						begin: /\x20+-l/,
					},
					{
						className: 'title',
						begin: /\x20+[^\x20]+\b/,
						endsParent: true
					}
				]
			}
		]
	};

	var EVENTS1 = {
		className: 'built_in',
		begin: /^on\x20+[^:\x20]+:(action|notice|text):[^:]+:(\?|#[^:]*|\*)/,
		end: /:/
	};

	var EVENTS2 = {
		className: 'built_in',
		begin: /^on\x20+[^:\x20]+:(active|input|tabcomp):(\*|#[^:]*|\?|=|!|@[^:]*)/,
		end: /:/
	};

	var EVENTS3 = {
		className: 'built_in',
		begin: /^on\x20+[^:\x20]+:(agent|appactive|(dis)?connect(fail)?|dns|exit|(un)?load|(midi|mp3|play|wave)end|nick|nosound|u?notify|ping|pong|quit|start|usermode)/,
		end: /:/
	};

	var EVENTS4 = {
		className: 'built_in',
		begin: /^on\x20+[^:\x20]+:((un)?ban|(de)?help|(de|server)?op|(de)?owner|(de)?voice|invite|join|kick|(server)?mode|part|rawmode|topic):(?:\*|#[^:]*)/,
		end: /:/
	};

	var EVENTS5 = {
		className: 'built_in',
		begin: /^on\x20+[^:\x20]+:(chat|ctcpreply|error|file(rcvd|sent)|(get|send)fail|logon|serv|signal|snotice|sock(close|listen|open|read|write)|udpread|vcmd|wallops):[^:]+/,
		end: /:/
	};

	var EVENTS6 = {
		className: 'built_in',
		begin: /^on\x20+[^:\x20]+:close:(\*|\?|=|!|@[^:]*)/,
		end: /:/
	};

	var EVENTS7 = {
		className: 'built_in',
		begin: /^on\x20+[^:\x20]+:dccserver:(chat|send|fserve)/,
		end: /:/
	};

	var EVENTS8 = {
		className: 'built_in',
		begin: /^on\x20+[^:\x20]+:dialog:[^:]+:(init|close|edit|sclick|dclick|menu|scroll|mouse|rclick|drop|\*):[\d\-,\*]+/,
		end: /:/
	};

	var EVENTS9 = {
		className: 'built_in',
		begin: /^on\x20+[^:\x20]+:hotlink:[^:]+:(?:\*|#[^:]*|\?|=|!|@[^:]*)/,
		end: /:/
	};

	var EVENTS10 = {
		className: 'built_in',
		begin: /^on\x20+[^:\x20]+:key(down|up):(\*|@[^:]*):(\*|\d+(,\d+)*)/,
		end: /:/
	};

	var EVENTS11 = {
		className: 'built_in',
		begin: /^on\x20+[^:\x20]+:open:(\*|\?|=|!|@[^:]*):[^:]+/,
		end: /:/
	};

	var EVENTS12 = {
		className: 'built_in',
		begin: /^on\x20+[^:\x20]+:parseline:(\*|in|out):[^:]+/,
		end: /:/
	};

	var EVENTS13 = {
		className: 'built_in',
		begin: /^raw\x20+[^:\x20]+:[^:]+/,
		end: /:/
	};

	var EVENTS14 = {
		className: 'built_in',
		begin: /^ctcp\x20+[^:\x20]+:[^:]+:(\*|#.*|\?)/,
		end: /:/
	};

	var CODE = {
		className: 'code',
		begin: /{/,
		end: /^}$/,
		contains: [
			{
				className: 'keyword',
				beginKeywords: 'if elseif else while break continue halt haltdef goto return'
			},
			{
				className: 'leteral',
				beginKeywords: '$true $false $null'
			}
		]
	};

	return {
  		aliases: ['mrc'],
		case_insensitive: true,
		keywords: {
			keyword: 'if elseif else while break continue halt haltdef goto return',
			leteral: '$true $false $null'
		},
  		contains: [
			COMMENT_DOC,
			COMMENT_BLOCK,
			COMMENT_LINE,
			STATEMENTS,
			EVENTS1,
			EVENTS2,
			EVENTS3,
			EVENTS4,
			EVENTS5,
			EVENTS6,
			EVENTS7,
			EVENTS8,
			EVENTS9,
			EVENTS10,
			EVENTS11,
			EVENTS12,
			EVENTS13,
			EVENTS14,
			CODE
  		]
  	};
}

still needs commands, identifiers, menu, among other things.


#4

@SykO, how are you testing? I’ve got mine on display on a raspberry pi here: http://highlight.duckdns.org/highlight.js/build/demo/

I quite like yours! Will you fork the highlight.js repo on GitHub and pr yours as well?


#5

I am testing it by building it using: node tools/build.js and previewing it in the file: tools/developer.html.

yeah that sounds good.