Skip to main content
Code Review

Return to Answer

replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link

@Mast @Mast pointed out something very simple and small.

@Mast pointed out something very simple and small.

@Mast pointed out something very simple and small.

added 1530 characters in body
Source Link
Ismael Miguel
  • 6.1k
  • 2
  • 23
  • 62

Mistake 4:

The lack of 'stricness' disturbed some people.

And it is a good point!

Now, 'use strict'; is present in the code.

The individual results for each element are returned in the form of an array.

Change 4:

@Mast pointed out something very simple and small.

The initialization had the following line:

var f=window.highlight = function(element, lang){//...

At first, it is completely unclear what f is doing.

I've changed it's name to fn, and added a description of what that variable is doing there.

(function(window){
 
 'use strict';
 
 //fn keeps an internal reference to avoid problems with rewritting the window.highlight
 var f=windowfn = window.highlight = function(element, lang){
 
 'use strict';
 
 if(element instanceof NodeList || element instanceof HTMLCollection)
 {
 for(var i = 0, l = element.length;length, results = []; i<l; i++)
 {
 try
 {
 fresults[i] = fn( element[i], lang );
 }
 catch(e)
 {
 //welogs wantthe message, to give a chance to all the other elements
 (console.error || console.log).call( console, e.message );
 results[i] = false;
 }
 }
 return true;results;
 }
 
 if(!(element instanceof Element))
 {
 throw new TypeError( 'The 1st parameter must be an Element or NodeList' );
 }
 
 lang = lang || element.getAttribute('data-lang');
 
 if(!lang)
 {
 throw new TypeError( 'Missing language definition. Set the 2nd parameter or the attribute data-lang' );
 }
 
 var lang_defs = ffn.langs[lang];
 
 if(!lang_defs)
 {
 throw new TypeError( 'The language "' + lang + '" was not yet defined' );
 }
 
 //create a document fragment, to avoid reflow and increase performance
 var fragment = document.createDocumentFragment(),
 div = document.createElement('div');
 
 div.innerHTML = element.innerHTML;
 fragment.appendChild(div);
 
 for(var i = 0, l = lang_defs.length; i<l; i++)
 {
 var html = '';
 
 for(var j = 0, k = div.childNodes.length; j<k; j++)
 {
 if(div.childNodes[j].nodeType === 3)
 {
 html += div.childNodes[j].nodeValue
 .replace(
 lang_defs[i].match,
 /*shortcut to decide if the lang_defs[i].replace is one of those types
 *if so, passes it directly
 *otherwise, makes a string matching based on the object
 */
 {'string':1, 'function':1}[ typeof lang_defs[i].replace ]
 ? lang_defs[i].replace
 : '<' + lang_defs[i].replace.tag +
 ' class="' + lang_defs[i]['class'] + '">' +
 lang_defs[i].replace.text +
 '</' + lang_defs[i].replace.tag + '>'
 );
 }
 else
 {
 html += div.childNodes[j].outerHTML;
 }
 }
 
 //refreshes the HTML, before doing anything else
 div.innerHTML = html;
 
 if('function' === typeof lang_defs[i].patch)
 {
 var returned = lang_defs[i].patch.call( div );
 if('string' === typeof returned)
 {
 div.innerHTML = returned;
 }
 }
 }
 
 
 //only change at the end, to avoid unnecessary reflowreflows
 element.className += ' highlight ' + lang;
 element.innerHTML = div.innerHTML;
 
 return true;
 };
 //default replace object
 ffn.default_replace = {'tag': 'span', 'text': '1ドル'};
 
 //all the languages will be added here
 ffn.langs = {};
})(Function('return this')());//just be sure that we have the real window
//main file, containing the main function
(function(window){
 
 'use strict';
 
 //fn keeps an internal reference to avoid problems with rewritting the window.highlight
 var fn = window.highlight = function(element, lang){
 
 var'use f=window.highlightstrict';
 = function 
 if(element, lang){
instanceof NodeList || element instanceof HTMLCollection)
 {
 iffor(elementvar instanceofi NodeList= ||0, l = element.length, instanceofresults HTMLCollection= []; i<l; i++)
 {
 for(var i = 0, l = element.length; i<l; i++)try
 {
 try
 {
 results[i] = ffn( element[i], lang );
 }
 catch(e)
  {
 //we want to give a chance to all the other elements
 (console.error || console.log).call( console, e.message );
 }
 }
 return true;
 }
 
 if(!catch(element instanceof Element)e)
 {
 {
 throw new TypeError( 'The 1st parameter must be an Element or NodeList' );
 //logs the message, to give a chance to all the other }elements
 lang =( langconsole.error || elementconsole.getAttribute('data-lang');
 
 log if(!lang)
 {
 throw new TypeError.call( 'Missing languageconsole, definitione. Set the 2nd parameter or the attribute data-lang'message );
 }
 var lang_defsresults[i] = f.langs[lang];
 
 if(!lang_defs)
 {false;
 throw new TypeError( 'The language "' + lang + '" was not yet defined' );}
 }
 return results;
 }
 
 if(!(element instanceof Element))
 {
 throw new TypeError( 'The 1st parameter must be an Element or NodeList' );
 }
 
  lang = lang || element.getAttribute('data-lang');
 
 if(!lang)
 {
 throw new TypeError( 'Missing language definition. Set the 2nd parameter or the attribute data-lang' );
 }
  
 var lang_defs = fn.langs[lang];
 
 if(!lang_defs)
 {
 throw new TypeError( 'The language "' + lang + '" was not yet defined' );
 }
 
 //create a document fragment, to avoid reflow and increase performance
 var fragment = document.createDocumentFragment(),
 div = document.createElement('div');
 
 div.innerHTML = element.innerHTML;
 fragment.appendChild(div);
 
 for(var i = 0, l = lang_defs.length; i<l; i++)
 {
 var html = '';
 
 for(var ij = 0, lk = lang_defsdiv.childNodes.length; i<l;j<k; i++j++)
 {
 var html = '';
 
 forif(var j = 0, k = div.childNodeschildNodes[j].length;nodeType j<k;=== j++3)
 {
 if(div.childNodes[j].nodeType === 3)
 {
 html += div.childNodes[j].nodeValue
 .replace(
 lang_defs[i].match,
 /*shortcut to decide if the lang_defs[i].replace is one of those types
 *if so, passes it directly
 *otherwise, makes a string matching based on the object
 */
 {'string':1, 'function':1}[ typeof lang_defs[i].replace ]
 ? lang_defs[i].replace
 : '<' + lang_defs[i].replace.tag +
 ' class="' + lang_defs[i]['class'] + '">' +
 lang_defs[i].replace.text +
 '</' + lang_defs[i].replace.tag + '>'
 );
 }
 else
 {
 html += div.childNodes[j].outerHTML;
 }
 }
 
 //refreshes the HTML, before doing anything else
 div.innerHTML = html;
 
 if('function' === typeof lang_defs[i].patch)
 {
 var returned = lang_defs[i].patch.call( div );
 if('string' === typeof returned)
 {
 html += div.innerHTML = returned;
 }childNodes[j].outerHTML;
 }
 }
 
 //only change atrefreshes the endHTML, to avoid unnecessary reflow
  element.className += ' highlightbefore 'doing +anything lang;else
 elementdiv.innerHTML = div.innerHTML;html;
 
 returnif('function' true;=== typeof lang_defs[i].patch)
 } {
 var returned = lang_defs[i].patch.call( div );
 if('string' === typeof returned)
 //default replace object {
 f div.default_replaceinnerHTML = {'tag':returned;
 'span', 'text': '1ドル'};
 }
 }
 
 //allonly change at the languagesend, willto beavoid addedunnecessary herereflows
 felement.langsclassName += ' highlight ' + lang;
  element.innerHTML = {div.innerHTML;
 
 return true;
 };
 })(Function('return//default this')())replace object
 fn.default_replace = {'tag': 'span', 'text': '1ドル'};//justall the languages will be sureadded thathere
 we have the realfn.langs window= {};
})(Function('return this')());//==========================================================just be sure that we have the real window
 // sql syntax highlight, anothed different file

 (function(window){//==========================================================
// sql syntax highlight, anothed different file
(function(window){
  'use strict';
 if('function' === typeof window.highlight)
 {
 window.highlight.langs.sql=[
 {
 'class':'string',
 'match':/([bn]?"(?:[^"]|[\\"]")*"|[bn]?'(?:[^']|[\\']')*')(?=[\b\s\(\),;\$#\+\-\*\/]|$)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'comment',
 'match':/((?:\/\/|\-\-\s|#)[^\r\n]*|\/\*(?:[^*]|\*[^\/])*(?:\*\/|$))/g,
 'replace':window.highlight.default_replace,
 'patch':function(){
 'use strict';
  return this.innerHTML.replace(
 /((?:\/\/|\-\-\s|#)[^\r\n]*|\/\*(?:[^*]|\*[^\/])*(?:\*\/|$))/g,
 '1ドル</span>'
 ).replace(//matches single-line comments
 /<span class="comment">((?:#|-- |\/\/)(?:.|<\/span><span class="[^"]+">([^<])<\/span>)*)([\r\n]|$)/g,
 function(_,part1,part2,part3){
 return '<span class="comment">'+
 //cleans up all spans
 ((part1||'')+(part2||'')).replace(/<\/?span(?: class="[^"]+")?>/g,'')+
 '</span>'+
 (part3||'');
 }
 ).replace(//matches multi-line comments
 /<span class="comment">(\/\*(?:[^*]|\*[^\/])+(?:\*\/(?:<\/span>)?|$))/g,
 function(_,part1){
 return '<span class="comment">'+
 //cleans up all spans
 ((part1||'')).replace(/<\/?span(?: class="[^"]+")?>/g,'')+
 '</span>';
 }
 );
 }
 },
 {
 /* 
 * numbers aren't that 'regular' and many edge-cases were left behind 
 * with the help of @MLM (http://stackoverflow.com/users/796832/mlm), 
 * we were able to make this work. 
 * he took over the regex and patched it all up, I did the replace string 
 */
 'match':/((?:^|\b|\(|\s|,))(?![a-z_]+)([+\-]?\d+(?:\.\d+)?(?:[eE]-?\d+)?)((?=$|\b|\s|\(|\)|,|;))/g,
 'replace':'1ドル<span class="number">2ドル</span>3ドル'
 },
 {
 'class':'name',
 'match':/(`[^`]+`)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'var',
 'match':/(@@?[a-z_][a-z_\d]*)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'keyword',
 //the keyword replace must have an aditional check (`(?!\()` after the name), due to the function replace()
 'match':/\b(accessible|add|all|alter|analyze|and|as|asc|asensitive|before|between|bigint|binary|blob|both|by|call|cascade|case|change|char|character|check|collate|column|condition|constraint|continue|convert|create|cross|current_date|current_time|current_timestamp|current_user|cursor|database|databases|day_hour|day_microsecond|day_minute|day_second|dec|decimal|declare|default|delayed|delete|desc|describe|deterministic|distinct|distinctrow|div|double|drop|dual|each|else|elseif|enclosed|escaped|exists|exit|explain|false|fetch|float|float4|float8|for|force|foreign|from|fulltext|generated|get|grant|group|having|high_priority|hour_microsecond|hour_minute|hour_second|if|ignore|in|index|infile|inner|inout|insensitive|insert|int|int1|int2|int3|int4|int8|integer|interval|into|io_after_gtids|io_before_gtids|is|iterate|join|key|keys|kill|leading|leave|left|like|limit|linear|lines|load|localtime|localtimestamp|lock|long|longblob|longtext|loop|low_priority|master_bind|master_ssl_verify_server_cert|match|maxvalue|mediumblob|mediumint|mediumtext|middleint|minute_microsecond|minute_second|mod|modifies|natural|nonblocking|not|no_write_to_binlog|null|numeric|on|optimize|optimizer_costs|option|optionally|or|order|out|outer|outfile|parse_gcol_expr|partition|precision|primary|procedure|purge|range|read|reads|read_write|real|references|regexp|release|rename|repeat|replace(?!\()|require|resignal|restrict|return|revoke|right|rlike|schema|schemas|second_microsecond|select|sensitive|separator|set|show|signal|smallint|spatial|specific|sql|sqlexception|sqlstate|sqlwarning|sql_big_result|sql_calc_found_rows|sql_small_result|ssl|starting|stored|straight_join|table|terminated|then|tinyblob|tinyint|tinytext|to|trailing|trigger|true|undo|union|unique|unlock|unsigned|update|usage|use|using|utc_date|utc_time|utc_timestamp|values|varbinary|varchar|varcharacter|varying|virtual|when|where|while|with|write|xor|year_month|zerofill)\b/gi,
 'replace':window.highlight.default_replace
 },
 {
 'class':'func',
 'match':/\b([a-z_][a-z_\d]*)\b(?=\()/gi,
 'replace':window.highlight.default_replace
 },
 {
 'class':'name',
 'match':/\b([a-z\_][a-z_\d]*)\b/gi,
 'replace':window.highlight.default_replace
 }
 ];},
 {
 /* 
 * numbers aren't that 'regular' and many edge-cases were left behind 
 * with the help of @MLM (http://stackoverflow.com/users/796832/mlm), 
 * we were able to make this work. 
 * he took over the regex and patched it all up, I did the replace string 
 */
 'match':/((?:^|\b|\(|\s|,))(?![a-z_]+)([+\-]?\d+(?:\.\d+)?(?:[eE]-?\d+)?)((?=$|\b|\s|\(|\)|,|;))/g,
 'replace':'1ドル<span class="number">2ドル</span>3ドル'
 },
 {
 'class':'name',
 'match':/(`[^`]+`)/g,
 'replace':window.highlight.default_replace
 },
 {
  'class':'var',
 'match':/(@@?[a-z_][a-z_\d]*)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'keyword',
 //the keyword replace must have an aditional check (`(?!\()` after the name), due to the function replace()
 'match':/\b(accessible|add|all|alter|analyze|and|as|asc|asensitive|before|between|bigint|binary|blob|both|by|call|cascade|case|change|char|character|check|collate|column|condition|constraint|continue|convert|create|cross|current_date|current_time|current_timestamp|current_user|cursor|database|databases|day_hour|day_microsecond|day_minute|day_second|dec|decimal|declare|default|delayed|delete|desc|describe|deterministic|distinct|distinctrow|div|double|drop|dual|each|else|elseif|enclosed|escaped|exists|exit|explain|false|fetch|float|float4|float8|for|force|foreign|from|fulltext|generated|get|grant|group|having|high_priority|hour_microsecond|hour_minute|hour_second|if|ignore|in|index|infile|inner|inout|insensitive|insert|int|int1|int2|int3|int4|int8|integer|interval|into|io_after_gtids|io_before_gtids|is|iterate|join|key|keys|kill|leading|leave|left|like|limit|linear|lines|load|localtime|localtimestamp|lock|long|longblob|longtext|loop|low_priority|master_bind|master_ssl_verify_server_cert|match|maxvalue|mediumblob|mediumint|mediumtext|middleint|minute_microsecond|minute_second|mod|modifies|natural|nonblocking|not|no_write_to_binlog|null|numeric|on|optimize|optimizer_costs|option|optionally|or|order|out|outer|outfile|parse_gcol_expr|partition|precision|primary|procedure|purge|range|read|reads|read_write|real|references|regexp|release|rename|repeat|replace(?!\()|require|resignal|restrict|return|revoke|right|rlike|schema|schemas|second_microsecond|select|sensitive|separator|set|show|signal|smallint|spatial|specific|sql|sqlexception|sqlstate|sqlwarning|sql_big_result|sql_calc_found_rows|sql_small_result|ssl|starting|stored|straight_join|table|terminated|then|tinyblob|tinyint|tinytext|to|trailing|trigger|true|undo|union|unique|unlock|unsigned|update|usage|use|using|utc_date|utc_time|utc_timestamp|values|varbinary|varchar|varcharacter|varying|virtual|when|where|while|with|write|xor|year_month|zerofill)\b/gi,
 'replace':window.highlight.default_replace
 },
 {
 'class':'func',
 'match':/\b([a-z_][a-z_\d]*)\b(?=\()/gi,
 'replace':window.highlight.default_replace
 },
 {
 'class':'name',
 'match':/\b([a-z\_][a-z_\d]*)\b/gi,
 'replace':window.highlight.default_replace
 }
 ];
 }
})(Function('return this')());
//=========================================================
// execution example:
window.onload = function(){
 
 highlight(document.getElementsByTagName('pre')[0]);
 
}
/*styling for this example only*/
p {
 font-family:sans-serif;
 margin-bottom: 0px;
}
pre {margin-top:5px;}
/*console theme, main file*/
.highlight, .highlight *{
 background:black;
 color:white;
 font-family:'Consolas',monospace;
 font-size:16px;
 word-wrap: break-word;
 white-space: pre;
}
/*sql style, different file*/
.highlight.sql .keyword{color:teal;}
.highlight.sql .string{color:red;}
.highlight.sql .func{color:purple;}
.highlight.sql .number{color:#0F0;}
.highlight.sql .name{color:olive;}
.highlight.sql .var{color:green;}
.highlight.sql .comment{color:gray;}
<p>Simple example:</p>
<pre data-lang="sql">
insert into `table` select * from `_copy` where id &lt; 55;

</pre>
<p>Simple example, without language defined:</p>

<pre>
select "This will be 'unhighlighted'";
</pre>
<p>Complex example:</p>
<pre data-lang="sql">
 
CREATE TABLE `shop` (
 article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
 dealer CHAR(20) DEFAULT '' NOT NULL,
 price DOUBLE(16,2) DEFAULT '0.00' NOT NULL,
 PRIMARY KEY(article, dealer));
INSERT INTO shop VALUES
 (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),
 (3,'C',1.69),(3,'D',-1.25),(4,'D',19.95);
 
#This is an example of sql a = 'b', 'c'
 
SELECT MAX(article) AS article FROM shop;
SELECT s1.article, s1.dealer, s1.price
FROM shop s1
LEFT JOIN shop s2 ON s1.price &lt; s2.price
WHERE s2.article IS NULL;
 
SELECT article, MAX(price) AS price
FROM shop
GROUP BY article;
 
SELECT article, dealer, price
FROM shop s1
WHERE price=(SELECT MAX(s2.price)
 FROM shop s2
 WHERE s1.article = s2.article);
SELECT @min_price:=MIN(price),@max_price:=MAX(price) FROM shop;
SELECT * FROM shop WHERE price=@min_price OR price=@max_price;
 
 /*
 
 a string =' ',
 
 */
select '1'#comment
 /*''*/ or 2;
select "Also has support for "" &lt;-- that style of quotes",
 '''Like this as well!''';
</pre>
(function(window){
 
 var f=window.highlight = function(element, lang){
 
 if(element instanceof NodeList || element instanceof HTMLCollection)
 {
 for(var i = 0, l = element.length; i<l; i++)
 {
 try
 {
 f( element[i], lang );
 }
 catch(e)
 {
 //we want to give a chance to all the other elements
 (console.error || console.log).call( console, e.message );
 }
 }
 return true;
 }
 
 if(!(element instanceof Element))
 {
 throw new TypeError( 'The 1st parameter must be an Element or NodeList' );
 }
 
 lang = lang || element.getAttribute('data-lang');
 
 if(!lang)
 {
 throw new TypeError( 'Missing language definition. Set the 2nd parameter or the attribute data-lang' );
 }
 
 var lang_defs = f.langs[lang];
 
 if(!lang_defs)
 {
 throw new TypeError( 'The language "' + lang + '" was not yet defined' );
 }
 
 //create a document fragment, to avoid reflow and increase performance
 var fragment = document.createDocumentFragment(),
 div = document.createElement('div');
 
 div.innerHTML = element.innerHTML;
 fragment.appendChild(div);
 
 for(var i = 0, l = lang_defs.length; i<l; i++)
 {
 var html = '';
 
 for(var j = 0, k = div.childNodes.length; j<k; j++)
 {
 if(div.childNodes[j].nodeType === 3)
 {
 html += div.childNodes[j].nodeValue
 .replace(
 lang_defs[i].match,
 /*shortcut to decide if the lang_defs[i].replace is one of those types
 *if so, passes it directly
 *otherwise, makes a string matching based on the object
 */
 {'string':1, 'function':1}[ typeof lang_defs[i].replace ]
 ? lang_defs[i].replace
 : '<' + lang_defs[i].replace.tag +
 ' class="' + lang_defs[i]['class'] + '">' +
 lang_defs[i].replace.text +
 '</' + lang_defs[i].replace.tag + '>'
 );
 }
 else
 {
 html += div.childNodes[j].outerHTML;
 }
 }
 
 //refreshes the HTML, before doing anything else
 div.innerHTML = html;
 
 if('function' === typeof lang_defs[i].patch)
 {
 var returned = lang_defs[i].patch.call( div );
 if('string' === typeof returned)
 {
 div.innerHTML = returned;
 }
 }
 }
 
 
 //only change at the end, to avoid unnecessary reflow
 element.className += ' highlight ' + lang;
 element.innerHTML = div.innerHTML;
 
 return true;
 };
 //default replace object
 f.default_replace = {'tag': 'span', 'text': '1ドル'};
 
 //all the languages will be added here
 f.langs = {};
})(Function('return this')());//just be sure that we have the real window
 (function(window){
 
 var f=window.highlight = function(element, lang){
 
 if(element instanceof NodeList || element instanceof HTMLCollection)
 {
 for(var i = 0, l = element.length; i<l; i++)
 {
 try
 {
  f( element[i], lang );
 }
 catch(e)
  {
 //we want to give a chance to all the other elements
 (console.error || console.log).call( console, e.message );
 }
 }
 return true;
 }
 
 if(!(element instanceof Element))
 {
 throw new TypeError( 'The 1st parameter must be an Element or NodeList' );
 }
 lang = lang || element.getAttribute('data-lang');
 
  if(!lang)
 {
 throw new TypeError( 'Missing language definition. Set the 2nd parameter or the attribute data-lang' );
 }
 var lang_defs = f.langs[lang];
 
 if(!lang_defs)
 {
 throw new TypeError( 'The language "' + lang + '" was not yet defined' );
 }
 
 //create a document fragment, to avoid reflow and increase performance
 var fragment = document.createDocumentFragment(),
 div = document.createElement('div');
 
 div.innerHTML = element.innerHTML;
 fragment.appendChild(div);
 
 for(var i = 0, l = lang_defs.length; i<l; i++)
 {
 var html = '';
 
 for(var j = 0, k = div.childNodes.length; j<k; j++)
 {
 if(div.childNodes[j].nodeType === 3)
 {
 html += div.childNodes[j].nodeValue
 .replace(
 lang_defs[i].match,
 /*shortcut to decide if the lang_defs[i].replace is one of those types
 *if so, passes it directly
 *otherwise, makes a string matching based on the object
 */
 {'string':1, 'function':1}[ typeof lang_defs[i].replace ]
 ? lang_defs[i].replace
 : '<' + lang_defs[i].replace.tag +
 ' class="' + lang_defs[i]['class'] + '">' +
 lang_defs[i].replace.text +
 '</' + lang_defs[i].replace.tag + '>'
 );
 }
 else
 {
 html += div.childNodes[j].outerHTML;
 }
 }
 
 //refreshes the HTML, before doing anything else
 div.innerHTML = html;
 
 if('function' === typeof lang_defs[i].patch)
 {
 var returned = lang_defs[i].patch.call( div );
 if('string' === typeof returned)
 {
  div.innerHTML = returned;
 }
 }
 }
 
 //only change at the end, to avoid unnecessary reflow
  element.className += ' highlight ' + lang;
 element.innerHTML = div.innerHTML;
 
 return true;
 };
 //default replace object
 f.default_replace = {'tag': 'span', 'text': '1ドル'};
 
 //all the languages will be added here
 f.langs = {};
 })(Function('return this')());//just be sure that we have the real window
//==========================================================
 // sql syntax highlight, anothed different file

 (function(window){
 if('function' === typeof window.highlight)
 {
 window.highlight.langs.sql=[
 {
 'class':'string',
 'match':/([bn]?"(?:[^"]|[\\"]")*"|[bn]?'(?:[^']|[\\']')*')(?=[\b\s\(\),;\$#\+\-\*\/]|$)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'comment',
 'match':/((?:\/\/|\-\-\s|#)[^\r\n]*|\/\*(?:[^*]|\*[^\/])*(?:\*\/|$))/g,
 'replace':window.highlight.default_replace,
 'patch':function(){
 return this.innerHTML.replace(
 /((?:\/\/|\-\-\s|#)[^\r\n]*|\/\*(?:[^*]|\*[^\/])*(?:\*\/|$))/g,
 '1ドル</span>'
 ).replace(//matches single-line comments
 /<span class="comment">((?:#|-- |\/\/)(?:.|<\/span><span class="[^"]+">([^<])<\/span>)*)([\r\n]|$)/g,
 function(_,part1,part2,part3){
 return '<span class="comment">'+
 //cleans up all spans
 ((part1||'')+(part2||'')).replace(/<\/?span(?: class="[^"]+")?>/g,'')+
 '</span>'+
 (part3||'');
 }
 ).replace(//matches multi-line comments
 /<span class="comment">(\/\*(?:[^*]|\*[^\/])+(?:\*\/(?:<\/span>)?|$))/g,
 function(_,part1){
 return '<span class="comment">'+
 //cleans up all spans
 ((part1||'')).replace(/<\/?span(?: class="[^"]+")?>/g,'')+
 '</span>';
 }
 );
 }
 },
 {
 /* 
 * numbers aren't that 'regular' and many edge-cases were left behind 
 * with the help of @MLM (http://stackoverflow.com/users/796832/mlm), 
 * we were able to make this work. 
 * he took over the regex and patched it all up, I did the replace string 
 */
 'match':/((?:^|\b|\(|\s|,))(?![a-z_]+)([+\-]?\d+(?:\.\d+)?(?:[eE]-?\d+)?)((?=$|\b|\s|\(|\)|,|;))/g,
 'replace':'1ドル<span class="number">2ドル</span>3ドル'
 },
 {
 'class':'name',
 'match':/(`[^`]+`)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'var',
 'match':/(@@?[a-z_][a-z_\d]*)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'keyword',
 //the keyword replace must have an aditional check (`(?!\()` after the name), due to the function replace()
 'match':/\b(accessible|add|all|alter|analyze|and|as|asc|asensitive|before|between|bigint|binary|blob|both|by|call|cascade|case|change|char|character|check|collate|column|condition|constraint|continue|convert|create|cross|current_date|current_time|current_timestamp|current_user|cursor|database|databases|day_hour|day_microsecond|day_minute|day_second|dec|decimal|declare|default|delayed|delete|desc|describe|deterministic|distinct|distinctrow|div|double|drop|dual|each|else|elseif|enclosed|escaped|exists|exit|explain|false|fetch|float|float4|float8|for|force|foreign|from|fulltext|generated|get|grant|group|having|high_priority|hour_microsecond|hour_minute|hour_second|if|ignore|in|index|infile|inner|inout|insensitive|insert|int|int1|int2|int3|int4|int8|integer|interval|into|io_after_gtids|io_before_gtids|is|iterate|join|key|keys|kill|leading|leave|left|like|limit|linear|lines|load|localtime|localtimestamp|lock|long|longblob|longtext|loop|low_priority|master_bind|master_ssl_verify_server_cert|match|maxvalue|mediumblob|mediumint|mediumtext|middleint|minute_microsecond|minute_second|mod|modifies|natural|nonblocking|not|no_write_to_binlog|null|numeric|on|optimize|optimizer_costs|option|optionally|or|order|out|outer|outfile|parse_gcol_expr|partition|precision|primary|procedure|purge|range|read|reads|read_write|real|references|regexp|release|rename|repeat|replace(?!\()|require|resignal|restrict|return|revoke|right|rlike|schema|schemas|second_microsecond|select|sensitive|separator|set|show|signal|smallint|spatial|specific|sql|sqlexception|sqlstate|sqlwarning|sql_big_result|sql_calc_found_rows|sql_small_result|ssl|starting|stored|straight_join|table|terminated|then|tinyblob|tinyint|tinytext|to|trailing|trigger|true|undo|union|unique|unlock|unsigned|update|usage|use|using|utc_date|utc_time|utc_timestamp|values|varbinary|varchar|varcharacter|varying|virtual|when|where|while|with|write|xor|year_month|zerofill)\b/gi,
 'replace':window.highlight.default_replace
 },
 {
 'class':'func',
 'match':/\b([a-z_][a-z_\d]*)\b(?=\()/gi,
 'replace':window.highlight.default_replace
 },
 {
 'class':'name',
 'match':/\b([a-z\_][a-z_\d]*)\b/gi,
 'replace':window.highlight.default_replace
 }
 ];
 }
})(Function('return this')());
//=========================================================
// execution example:
window.onload = function(){
 
 highlight(document.getElementsByTagName('pre')[0]);
 
}
/*console theme, main file*/
.highlight, .highlight *{
 background:black;
 color:white;
 font-family:'Consolas',monospace;
 font-size:16px;
 word-wrap: break-word;
 white-space: pre;
}
/*sql style, different file*/
.highlight.sql .keyword{color:teal;}
.highlight.sql .string{color:red;}
.highlight.sql .func{color:purple;}
.highlight.sql .number{color:#0F0;}
.highlight.sql .name{color:olive;}
.highlight.sql .var{color:green;}
.highlight.sql .comment{color:gray;}
<pre data-lang="sql">
 
CREATE TABLE `shop` (
 article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
 dealer CHAR(20) DEFAULT '' NOT NULL,
 price DOUBLE(16,2) DEFAULT '0.00' NOT NULL,
 PRIMARY KEY(article, dealer));
INSERT INTO shop VALUES
 (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),
 (3,'C',1.69),(3,'D',-1.25),(4,'D',19.95);
 
#This is an example of sql a = 'b', 'c'
 
SELECT MAX(article) AS article FROM shop;
SELECT s1.article, s1.dealer, s1.price
FROM shop s1
LEFT JOIN shop s2 ON s1.price &lt; s2.price
WHERE s2.article IS NULL;
 
SELECT article, MAX(price) AS price
FROM shop
GROUP BY article;
 
SELECT article, dealer, price
FROM shop s1
WHERE price=(SELECT MAX(s2.price)
 FROM shop s2
 WHERE s1.article = s2.article);
SELECT @min_price:=MIN(price),@max_price:=MAX(price) FROM shop;
SELECT * FROM shop WHERE price=@min_price OR price=@max_price;
 
 /*
 
 a string =' ',
 
 */
select '1'#comment
 /*''*/ or 2;
</pre>

Mistake 4:

The lack of 'stricness' disturbed some people.

And it is a good point!

Now, 'use strict'; is present in the code.

The individual results for each element are returned in the form of an array.

Change 4:

@Mast pointed out something very simple and small.

The initialization had the following line:

var f=window.highlight = function(element, lang){//...

At first, it is completely unclear what f is doing.

I've changed it's name to fn, and added a description of what that variable is doing there.

(function(window){
 
 'use strict';
 
 //fn keeps an internal reference to avoid problems with rewritting the window.highlight
 var fn = window.highlight = function(element, lang){
 
 'use strict';
 
 if(element instanceof NodeList || element instanceof HTMLCollection)
 {
 for(var i = 0, l = element.length, results = []; i<l; i++)
 {
 try
 {
 results[i] = fn( element[i], lang );
 }
 catch(e)
 {
 //logs the message, to give a chance to all the other elements
 (console.error || console.log).call( console, e.message );
 results[i] = false;
 }
 }
 return results;
 }
 
 if(!(element instanceof Element))
 {
 throw new TypeError( 'The 1st parameter must be an Element or NodeList' );
 }
 
 lang = lang || element.getAttribute('data-lang');
 
 if(!lang)
 {
 throw new TypeError( 'Missing language definition. Set the 2nd parameter or the attribute data-lang' );
 }
 
 var lang_defs = fn.langs[lang];
 
 if(!lang_defs)
 {
 throw new TypeError( 'The language "' + lang + '" was not yet defined' );
 }
 
 //create a document fragment, to avoid reflow and increase performance
 var fragment = document.createDocumentFragment(),
 div = document.createElement('div');
 
 div.innerHTML = element.innerHTML;
 fragment.appendChild(div);
 
 for(var i = 0, l = lang_defs.length; i<l; i++)
 {
 var html = '';
 
 for(var j = 0, k = div.childNodes.length; j<k; j++)
 {
 if(div.childNodes[j].nodeType === 3)
 {
 html += div.childNodes[j].nodeValue
 .replace(
 lang_defs[i].match,
 /*shortcut to decide if the lang_defs[i].replace is one of those types
 *if so, passes it directly
 *otherwise, makes a string matching based on the object
 */
 {'string':1, 'function':1}[ typeof lang_defs[i].replace ]
 ? lang_defs[i].replace
 : '<' + lang_defs[i].replace.tag +
 ' class="' + lang_defs[i]['class'] + '">' +
 lang_defs[i].replace.text +
 '</' + lang_defs[i].replace.tag + '>'
 );
 }
 else
 {
 html += div.childNodes[j].outerHTML;
 }
 }
 
 //refreshes the HTML, before doing anything else
 div.innerHTML = html;
 
 if('function' === typeof lang_defs[i].patch)
 {
 var returned = lang_defs[i].patch.call( div );
 if('string' === typeof returned)
 {
 div.innerHTML = returned;
 }
 }
 }
 
 
 //only change at the end, to avoid unnecessary reflows
 element.className += ' highlight ' + lang;
 element.innerHTML = div.innerHTML;
 
 return true;
 };
 //default replace object
 fn.default_replace = {'tag': 'span', 'text': '1ドル'};
 
 //all the languages will be added here
 fn.langs = {};
})(Function('return this')());//just be sure that we have the real window
//main file, containing the main function
(function(window){
 
 'use strict';
 
 //fn keeps an internal reference to avoid problems with rewritting the window.highlight
 var fn = window.highlight = function(element, lang){
 
 'use strict';
  
 if(element instanceof NodeList || element instanceof HTMLCollection)
 {
 for(var i = 0, l = element.length, results = []; i<l; i++)
 {
 try
 {
 results[i] = fn( element[i], lang );
 }
 catch(e)
 {
 //logs the message, to give a chance to all the other elements
 ( console.error || console.log ).call( console, e.message );
 results[i] = false;
 }
 }
 return results;
 }
 
 if(!(element instanceof Element))
 {
 throw new TypeError( 'The 1st parameter must be an Element or NodeList' );
 }
 
  lang = lang || element.getAttribute('data-lang');
 
 if(!lang)
 {
 throw new TypeError( 'Missing language definition. Set the 2nd parameter or the attribute data-lang' );
 }
  
 var lang_defs = fn.langs[lang];
 
 if(!lang_defs)
 {
 throw new TypeError( 'The language "' + lang + '" was not yet defined' );
 }
 
 //create a document fragment, to avoid reflow and increase performance
 var fragment = document.createDocumentFragment(),
 div = document.createElement('div');
 
 div.innerHTML = element.innerHTML;
 fragment.appendChild(div);
 
 for(var i = 0, l = lang_defs.length; i<l; i++)
 {
 var html = '';
 
 for(var j = 0, k = div.childNodes.length; j<k; j++)
 {
 if(div.childNodes[j].nodeType === 3)
 {
 html += div.childNodes[j].nodeValue
 .replace(
 lang_defs[i].match,
 /*shortcut to decide if the lang_defs[i].replace is one of those types
 *if so, passes it directly
 *otherwise, makes a string matching based on the object
 */
 {'string':1, 'function':1}[ typeof lang_defs[i].replace ]
 ? lang_defs[i].replace
 : '<' + lang_defs[i].replace.tag +
 ' class="' + lang_defs[i]['class'] + '">' +
 lang_defs[i].replace.text +
 '</' + lang_defs[i].replace.tag + '>'
 );
 }
 else
 {
 html += div.childNodes[j].outerHTML;
 }
 }
 
 //refreshes the HTML, before doing anything else
 div.innerHTML = html;
 
 if('function' === typeof lang_defs[i].patch)
  {
 var returned = lang_defs[i].patch.call( div );
 if('string' === typeof returned)
  {
  div.innerHTML = returned;
 }
 }
 }
 
 //only change at the end, to avoid unnecessary reflows
 element.className += ' highlight ' + lang;
  element.innerHTML = div.innerHTML;
 
 return true;
 };
 //default replace object
 fn.default_replace = {'tag': 'span', 'text': '1ドル'};//all the languages will be added here
 fn.langs = {};
})(Function('return this')());//just be sure that we have the real window
//==========================================================
// sql syntax highlight, anothed different file
(function(window){
  'use strict';
 if('function' === typeof window.highlight)
 {
 window.highlight.langs.sql=[
 {
 'class':'string',
 'match':/([bn]?"(?:[^"]|[\\"]")*"|[bn]?'(?:[^']|[\\']')*')(?=[\b\s\(\),;\$#\+\-\*\/]|$)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'comment',
 'match':/((?:\/\/|\-\-\s|#)[^\r\n]*|\/\*(?:[^*]|\*[^\/])*(?:\*\/|$))/g,
 'replace':window.highlight.default_replace,
 'patch':function(){
 'use strict';
  return this.innerHTML.replace(
 /((?:\/\/|\-\-\s|#)[^\r\n]*|\/\*(?:[^*]|\*[^\/])*(?:\*\/|$))/g,
 '1ドル</span>'
 ).replace(//matches single-line comments
 /<span class="comment">((?:#|-- |\/\/)(?:.|<\/span><span class="[^"]+">([^<])<\/span>)*)([\r\n]|$)/g,
 function(_,part1,part2,part3){
 return '<span class="comment">'+
 //cleans up all spans
 ((part1||'')+(part2||'')).replace(/<\/?span(?: class="[^"]+")?>/g,'')+
 '</span>'+
 (part3||'');
 }
 ).replace(//matches multi-line comments
 /<span class="comment">(\/\*(?:[^*]|\*[^\/])+(?:\*\/(?:<\/span>)?|$))/g,
 function(_,part1){
 return '<span class="comment">'+
 //cleans up all spans
 ((part1||'')).replace(/<\/?span(?: class="[^"]+")?>/g,'')+
 '</span>';
 }
 );
 }
 },
 {
 /* 
 * numbers aren't that 'regular' and many edge-cases were left behind 
 * with the help of @MLM (http://stackoverflow.com/users/796832/mlm), 
 * we were able to make this work. 
 * he took over the regex and patched it all up, I did the replace string 
 */
 'match':/((?:^|\b|\(|\s|,))(?![a-z_]+)([+\-]?\d+(?:\.\d+)?(?:[eE]-?\d+)?)((?=$|\b|\s|\(|\)|,|;))/g,
 'replace':'1ドル<span class="number">2ドル</span>3ドル'
 },
 {
 'class':'name',
 'match':/(`[^`]+`)/g,
 'replace':window.highlight.default_replace
 },
 {
  'class':'var',
 'match':/(@@?[a-z_][a-z_\d]*)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'keyword',
 //the keyword replace must have an aditional check (`(?!\()` after the name), due to the function replace()
 'match':/\b(accessible|add|all|alter|analyze|and|as|asc|asensitive|before|between|bigint|binary|blob|both|by|call|cascade|case|change|char|character|check|collate|column|condition|constraint|continue|convert|create|cross|current_date|current_time|current_timestamp|current_user|cursor|database|databases|day_hour|day_microsecond|day_minute|day_second|dec|decimal|declare|default|delayed|delete|desc|describe|deterministic|distinct|distinctrow|div|double|drop|dual|each|else|elseif|enclosed|escaped|exists|exit|explain|false|fetch|float|float4|float8|for|force|foreign|from|fulltext|generated|get|grant|group|having|high_priority|hour_microsecond|hour_minute|hour_second|if|ignore|in|index|infile|inner|inout|insensitive|insert|int|int1|int2|int3|int4|int8|integer|interval|into|io_after_gtids|io_before_gtids|is|iterate|join|key|keys|kill|leading|leave|left|like|limit|linear|lines|load|localtime|localtimestamp|lock|long|longblob|longtext|loop|low_priority|master_bind|master_ssl_verify_server_cert|match|maxvalue|mediumblob|mediumint|mediumtext|middleint|minute_microsecond|minute_second|mod|modifies|natural|nonblocking|not|no_write_to_binlog|null|numeric|on|optimize|optimizer_costs|option|optionally|or|order|out|outer|outfile|parse_gcol_expr|partition|precision|primary|procedure|purge|range|read|reads|read_write|real|references|regexp|release|rename|repeat|replace(?!\()|require|resignal|restrict|return|revoke|right|rlike|schema|schemas|second_microsecond|select|sensitive|separator|set|show|signal|smallint|spatial|specific|sql|sqlexception|sqlstate|sqlwarning|sql_big_result|sql_calc_found_rows|sql_small_result|ssl|starting|stored|straight_join|table|terminated|then|tinyblob|tinyint|tinytext|to|trailing|trigger|true|undo|union|unique|unlock|unsigned|update|usage|use|using|utc_date|utc_time|utc_timestamp|values|varbinary|varchar|varcharacter|varying|virtual|when|where|while|with|write|xor|year_month|zerofill)\b/gi,
 'replace':window.highlight.default_replace
 },
 {
 'class':'func',
 'match':/\b([a-z_][a-z_\d]*)\b(?=\()/gi,
 'replace':window.highlight.default_replace
 },
 {
 'class':'name',
 'match':/\b([a-z\_][a-z_\d]*)\b/gi,
 'replace':window.highlight.default_replace
 }
 ];
 }
})(Function('return this')());
//=========================================================
// execution example:
window.onload = function(){
 
 highlight(document.getElementsByTagName('pre'));
 
}
/*styling for this example only*/
p {
 font-family:sans-serif;
 margin-bottom: 0px;
}
pre {margin-top:5px;}
/*console theme, main file*/
.highlight, .highlight *{
 background:black;
 color:white;
 font-family:'Consolas',monospace;
 font-size:16px;
 word-wrap: break-word;
 white-space: pre;
}
/*sql style, different file*/
.highlight.sql .keyword{color:teal;}
.highlight.sql .string{color:red;}
.highlight.sql .func{color:purple;}
.highlight.sql .number{color:#0F0;}
.highlight.sql .name{color:olive;}
.highlight.sql .var{color:green;}
.highlight.sql .comment{color:gray;}
<p>Simple example:</p>
<pre data-lang="sql">
insert into `table` select * from `_copy` where id &lt; 55;

</pre>
<p>Simple example, without language defined:</p>

<pre>
select "This will be 'unhighlighted'";
</pre>
<p>Complex example:</p>
<pre data-lang="sql">
 
CREATE TABLE `shop` (
 article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
 dealer CHAR(20) DEFAULT '' NOT NULL,
 price DOUBLE(16,2) DEFAULT '0.00' NOT NULL,
 PRIMARY KEY(article, dealer));
INSERT INTO shop VALUES
 (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),
 (3,'C',1.69),(3,'D',-1.25),(4,'D',19.95);
 
#This is an example of sql a = 'b', 'c'
 
SELECT MAX(article) AS article FROM shop;
SELECT s1.article, s1.dealer, s1.price
FROM shop s1
LEFT JOIN shop s2 ON s1.price &lt; s2.price
WHERE s2.article IS NULL;
 
SELECT article, MAX(price) AS price
FROM shop
GROUP BY article;
 
SELECT article, dealer, price
FROM shop s1
WHERE price=(SELECT MAX(s2.price)
 FROM shop s2
 WHERE s1.article = s2.article);
SELECT @min_price:=MIN(price),@max_price:=MAX(price) FROM shop;
SELECT * FROM shop WHERE price=@min_price OR price=@max_price;
 
 /*
 
 a string =' ',
 
 */
select '1'#comment
 /*''*/ or 2;
select "Also has support for "" &lt;-- that style of quotes",
 '''Like this as well!''';
</pre>
added 1101 characters in body
Source Link
Ismael Miguel
  • 6.1k
  • 2
  • 23
  • 62

Also, the exception about the language being missing was adjusted.

Change 3:

You can now pass a set of elements (NodeList or HTMLCollection) and the elements will be highlighted.

The exceptions that are thrown will be handled differently, giving the other elements a chance.

(function(window){
 
 var f=window.highlight = function(element, lang){
 
 if(element instanceof NodeList || element instanceof HTMLCollection)
 {
 for(var i = 0, l = element.length; i<l; i++)
 {
 try
 {
 f( element[i], lang );
 }
 catch(e)
 {
 //we want to give a chance to all the other elements
 (console.error || console.log).call( console, e.message );
 }
 }
 return true;
 }
 
 if(!(element instanceof Element))
 {
 throw new TypeError( 'The 2nd1st parameter must be an Element'Element or NodeList' );
 }
 
 lang = lang || element.getAttribute('data-lang') || '';;
 
 if(!lang)
 {
 throw new TypeError( 'Missing language definition. Set the 2nd parameter or the attribute data-lang' );
 }
 
 var lang_defs = f.langs[lang];
 
 if(!lang_defs)
 {
 throw new TypeError( 'The language "' + lang + '" was not yet defined' );
 }
 
 //create a document fragment, to avoid reflow and increase performance
 var fragment = document.createDocumentFragment(),
 div = document.createElement('div');
 
 div.innerHTML = element.innerHTML;
 fragment.appendChild(div);
 
 for(var i = 0, l = lang_defs.length; i<l; i++)
 {
 var html = '';
 
 for(var j = 0, k = div.childNodes.length; j<k; j++)
 {
 if(div.childNodes[j].nodeType === 3)
 {
 html += div.childNodes[j].nodeValue
 .replace(
 lang_defs[i].match,
 /*shortcut to decide if the lang_defs[i].replace is one of those types
 *if so, passes it directly
 *otherwise, makes a string matching based on the object
 */
 {'string':1, 'function':1}[ typeof lang_defs[i].replace ]
 ? lang_defs[i].replace
 : '<' + lang_defs[i].replace.tag +
 ' class="' + lang_defs[i]['class'] + '">' +
 lang_defs[i].replace.text +
 '</' + lang_defs[i].replace.tag + '>'
 );
 }
 else
 {
 html += div.childNodes[j].outerHTML;
 }
 }
 
 //refreshes the HTML, before doing anything else
 div.innerHTML = html;
 
 if('function' === typeof lang_defs[i].patch)
 {
 var returned = lang_defs[i].patch.call( div );
 if('string' === typeof returned)
 {
 div.innerHTML = returned;
 }
 }
 }
 
 
 //only change at the end, to avoid unnecessary reflow
 element.className += ' highlight ' + lang;
 element.innerHTML = div.innerHTML;
 
 return true;
 };
 //default replace object
 f.default_replace = {'tag': 'span', 'text': '1ドル'};
 
 //all the languages will be added here
 f.langs = {};
})(Function('return this')());//just be sure that we have the real window
// highlight function, separated file
 (function(window){
 
 var f=window.highlight = function(element, lang){
 
 if(element instanceof NodeList || element instanceof HTMLCollection)
 {
 for(var i = 0, l = element.length; i<l; i++)
 {
 try
 {
 f( element[i], lang );
 }
 catch(e)
 {
 //we want to give a chance to all the other elements
 (console.error || console.log).call( console, e.message );
 }
 }
 return true;
 }
 
 if(!(element instanceof Element))
 {
 throw new TypeError( 'The 2nd1st parameter must be an Element'Element or NodeList' );
 }
 
 lang = lang || element.getAttribute('data-lang') || '';;
 
 if(!lang)
 {
 throw new TypeError( 'Missing language definition. Set the 2nd parameter or the attribute data-lang' );
 }
 
 var lang_defs = f.langs[lang];
 
 if(!lang_defs)
 {
 throw new TypeError( 'The language "' + lang + '" was not yet defined' );
 }
 
 //create a document fragment, to avoid reflow and increase performance
 var fragment = document.createDocumentFragment(),
 div = document.createElement('div');
 
 div.innerHTML = element.innerHTML;
 fragment.appendChild(div);
 
 for(var i = 0, l = lang_defs.length; i<l; i++)
 {
 var html = '';
 
 for(var j = 0, k = div.childNodes.length; j<k; j++)
 {
 if(div.childNodes[j].nodeType === 3)
 {
 html += div.childNodes[j].nodeValue
 .replace(
 lang_defs[i].match,
 /*shortcut to decide if the lang_defs[i].replace is one of those types
 *if so, passes it directly
 *otherwise, makes a string matching based on the object
 */
 {'string':1, 'function':1}[ typeof lang_defs[i].replace ]
 ? lang_defs[i].replace
 : '<' + lang_defs[i].replace.tag +
 ' class="' + lang_defs[i]['class'] + '">' +
 lang_defs[i].replace.text +
 '</' + lang_defs[i].replace.tag + '>'
 );
 }
 else
 {
 html += div.childNodes[j].outerHTML;
 }
 }
 
 //refreshes the HTML, before doing anything else
 div.innerHTML = html;
 
 if('function' === typeof lang_defs[i].patch)
 {
 var returned = lang_defs[i].patch.call( div );
 if('string' === typeof returned)
 {
 div.innerHTML = returned;
 }
 }
 }
 
 
 //only change at the end, to avoid unnecessary reflow
 element.className += ' highlight ' + lang;
 element.innerHTML = div.innerHTML;
 
 return true;
 };
 //default replace object
 f.default_replace = {'tag': 'span', 'text': '1ドル'};
 
 //all the languages will be added here
 f.langs = {};
 })(Function('return this')());//just be sure that we have the real window
//==========================================================
 // sql syntax highlight, anothed different file
 (function(window){
 if('function' === typeof window.highlight)
 {
 window.highlight.langs.sql=[
 {
 'class':'string',
 'match':/([bn]?"(?:[^"]|[\\"]")*"|[bn]?'(?:[^']|[\\']')*')(?=[\b\s\(\),;\$#\+\-\*\/]|$)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'comment',
 'match':/((?:\/\/|\-\-\s|#)[^\r\n]*|\/\*(?:[^*]|\*[^\/])*(?:\*\/|$))/g,
 'replace':window.highlight.default_replace,
 'patch':function(){
 return this.innerHTML.replace(
 /((?:\/\/|\-\-\s|#)[^\r\n]*|\/\*(?:[^*]|\*[^\/])*(?:\*\/|$))/g,
 '1ドル</span>'
 ).replace(//matches single-line comments
 /<span class="comment">((?:#|-- |\/\/)(?:.|<\/span><span class="[^"]+">([^<])<\/span>)*)([\r\n]|$)/g,
 function(_,part1,part2,part3){
 return '<span class="comment">'+
 //cleans up all spans
 ((part1||'')+(part2||'')).replace(/<\/?span(?: class="[^"]+")?>/g,'')+
 '</span>'+
 (part3||'');
 }
 ).replace(//matches multi-line comments
 /<span class="comment">(\/\*(?:[^*]|\*[^\/])+(?:\*\/(?:<\/span>)?|$))/g,
 function(_,part1){
 return '<span class="comment">'+
 //cleans up all spans
 ((part1||'')).replace(/<\/?span(?: class="[^"]+")?>/g,'')+
 '</span>';
 }
 );
 }
 },
 {
 /* 
 * numbers aren't that 'regular' and many edge-cases were left behind 
 * with the help of @MLM (http://stackoverflow.com/users/796832/mlm), 
 * we were able to make this work. 
 * he took over the regex and patched it all up, I did the replace string 
 */
 'match':/((?:^|\b|\(|\s|,))(?![a-z_]+)([+\-]?\d+(?:\.\d+)?(?:[eE]-?\d+)?)((?=$|\b|\s|\(|\)|,|;))/g,
 'replace':'1ドル<span class="number">2ドル</span>3ドル'
 },
 {
 'class':'name',
 'match':/(`[^`]+`)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'var',
 'match':/(@@?[a-z_][a-z_\d]*)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'keyword',
 //the keyword replace must have an aditional check (`(?!\()` after the name), due to the function replace()
 'match':/\b(accessible|add|all|alter|analyze|and|as|asc|asensitive|before|between|bigint|binary|blob|both|by|call|cascade|case|change|char|character|check|collate|column|condition|constraint|continue|convert|create|cross|current_date|current_time|current_timestamp|current_user|cursor|database|databases|day_hour|day_microsecond|day_minute|day_second|dec|decimal|declare|default|delayed|delete|desc|describe|deterministic|distinct|distinctrow|div|double|drop|dual|each|else|elseif|enclosed|escaped|exists|exit|explain|false|fetch|float|float4|float8|for|force|foreign|from|fulltext|generated|get|grant|group|having|high_priority|hour_microsecond|hour_minute|hour_second|if|ignore|in|index|infile|inner|inout|insensitive|insert|int|int1|int2|int3|int4|int8|integer|interval|into|io_after_gtids|io_before_gtids|is|iterate|join|key|keys|kill|leading|leave|left|like|limit|linear|lines|load|localtime|localtimestamp|lock|long|longblob|longtext|loop|low_priority|master_bind|master_ssl_verify_server_cert|match|maxvalue|mediumblob|mediumint|mediumtext|middleint|minute_microsecond|minute_second|mod|modifies|natural|nonblocking|not|no_write_to_binlog|null|numeric|on|optimize|optimizer_costs|option|optionally|or|order|out|outer|outfile|parse_gcol_expr|partition|precision|primary|procedure|purge|range|read|reads|read_write|real|references|regexp|release|rename|repeat|replace(?!\()|require|resignal|restrict|return|revoke|right|rlike|schema|schemas|second_microsecond|select|sensitive|separator|set|show|signal|smallint|spatial|specific|sql|sqlexception|sqlstate|sqlwarning|sql_big_result|sql_calc_found_rows|sql_small_result|ssl|starting|stored|straight_join|table|terminated|then|tinyblob|tinyint|tinytext|to|trailing|trigger|true|undo|union|unique|unlock|unsigned|update|usage|use|using|utc_date|utc_time|utc_timestamp|values|varbinary|varchar|varcharacter|varying|virtual|when|where|while|with|write|xor|year_month|zerofill)\b/gi,
 'replace':window.highlight.default_replace
 },
 {
 'class':'func',
 'match':/\b([a-z_][a-z_\d]*)\b(?=\()/gi,
 'replace':window.highlight.default_replace
 },
 {
 'class':'name',
 'match':/\b([a-z\_][a-z_\d]*)\b/gi,
 'replace':window.highlight.default_replace
 }
 ];
 }
 })(Function('return this')());
 //=========================================================
 // execution example:
 window.onload = function(){
 
 highlight(document.getElementsByTagName('pre')[0]);
 
 }
/*console theme, main file*/
.highlight, .highlight *{
 background:black;
 color:white;
 font-family:'Consolas',monospace;
 font-size:16px;
 word-wrap: break-word;
 white-space: pre;
}
/*sql style, different file*/
.highlight.sql .keyword{color:teal;}
.highlight.sql .string{color:red;}
.highlight.sql .func{color:purple;}
.highlight.sql .number{color:#0F0;}
.highlight.sql .name{color:olive;}
.highlight.sql .var{color:green;}
.highlight.sql .comment{color:gray;}
<pre data-lang="sql">
 
CREATE TABLE `shop` (
 article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
 dealer CHAR(20) DEFAULT '' NOT NULL,
 price DOUBLE(16,2) DEFAULT '0.00' NOT NULL,
 PRIMARY KEY(article, dealer));
INSERT INTO shop VALUES
 (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),
 (3,'C',1.69),(3,'D',-1.25),(4,'D',19.95);
 
#This is an example of sql a = 'b', 'c'
 
SELECT MAX(article) AS article FROM shop;
SELECT s1.article, s1.dealer, s1.price
FROM shop s1
LEFT JOIN shop s2 ON s1.price &lt; s2.price
WHERE s2.article IS NULL;
 
SELECT article, MAX(price) AS price
FROM shop
GROUP BY article;
 
SELECT article, dealer, price
FROM shop s1
WHERE price=(SELECT MAX(s2.price)
 FROM shop s2
 WHERE s1.article = s2.article);
SELECT @min_price:=MIN(price),@max_price:=MAX(price) FROM shop;
SELECT * FROM shop WHERE price=@min_price OR price=@max_price;
 
 /*
 
 a string =' ',
 
 */
select '1'#comment
 /*''*/ or 2;
</pre>
(function(window){
 
 var f=window.highlight = function(element, lang){
 
 if(!(element instanceof Element))
 {
 throw new TypeError( 'The 2nd parameter must be an Element' );
 }
 
 lang = lang || element.getAttribute('data-lang') || '';
 
 if(!lang)
 {
 throw new TypeError( 'Missing language definition. Set the 2nd parameter or the attribute data-lang' );
 }
 
 var lang_defs = f.langs[lang];
 
 if(!lang_defs)
 {
 throw new TypeError( 'The language "' + lang + '" was not yet defined' );
 }
 
 //create a document fragment, to avoid reflow and increase performance
 var fragment = document.createDocumentFragment(),
 div = document.createElement('div');
 
 div.innerHTML = element.innerHTML;
 fragment.appendChild(div);
 
 for(var i = 0, l = lang_defs.length; i<l; i++)
 {
 var html = '';
 
 for(var j = 0, k = div.childNodes.length; j<k; j++)
 {
 if(div.childNodes[j].nodeType === 3)
 {
 html += div.childNodes[j].nodeValue
 .replace(
 lang_defs[i].match,
 /*shortcut to decide if the lang_defs[i].replace is one of those types
 *if so, passes it directly
 *otherwise, makes a string matching based on the object
 */
 {'string':1, 'function':1}[ typeof lang_defs[i].replace ]
 ? lang_defs[i].replace
 : '<' + lang_defs[i].replace.tag +
 ' class="' + lang_defs[i]['class'] + '">' +
 lang_defs[i].replace.text +
 '</' + lang_defs[i].replace.tag + '>'
 );
 }
 else
 {
 html += div.childNodes[j].outerHTML;
 }
 }
 
 //refreshes the HTML, before doing anything else
 div.innerHTML = html;
 
 if('function' === typeof lang_defs[i].patch)
 {
 var returned = lang_defs[i].patch.call( div );
 if('string' === typeof returned)
 {
 div.innerHTML = returned;
 }
 }
 }
 
 
 //only change at the end, to avoid unnecessary reflow
 element.className += ' highlight ' + lang;
 element.innerHTML = div.innerHTML;
 
 return true;
 };
 //default replace object
 f.default_replace = {'tag': 'span', 'text': '1ドル'};
 
 //all the languages will be added here
 f.langs = {};
})(Function('return this')());//just be sure that we have the real window
// highlight function, separated file
 (function(window){
 
 var f=window.highlight = function(element, lang){
 
 if(!(element instanceof Element))
 {
 throw new TypeError( 'The 2nd parameter must be an Element' );
 }
 
 lang = lang || element.getAttribute('data-lang') || '';
 
 if(!lang)
 {
 throw new TypeError( 'Missing language definition. Set the 2nd parameter or the attribute data-lang' );
 }
 
 var lang_defs = f.langs[lang];
 
 if(!lang_defs)
 {
 throw new TypeError( 'The language "' + lang + '" was not yet defined' );
 }
 
 //create a document fragment, to avoid reflow and increase performance
 var fragment = document.createDocumentFragment(),
 div = document.createElement('div');
 
 div.innerHTML = element.innerHTML;
 fragment.appendChild(div);
 
 for(var i = 0, l = lang_defs.length; i<l; i++)
 {
 var html = '';
 
 for(var j = 0, k = div.childNodes.length; j<k; j++)
 {
 if(div.childNodes[j].nodeType === 3)
 {
 html += div.childNodes[j].nodeValue
 .replace(
 lang_defs[i].match,
 /*shortcut to decide if the lang_defs[i].replace is one of those types
 *if so, passes it directly
 *otherwise, makes a string matching based on the object
 */
 {'string':1, 'function':1}[ typeof lang_defs[i].replace ]
 ? lang_defs[i].replace
 : '<' + lang_defs[i].replace.tag +
 ' class="' + lang_defs[i]['class'] + '">' +
 lang_defs[i].replace.text +
 '</' + lang_defs[i].replace.tag + '>'
 );
 }
 else
 {
 html += div.childNodes[j].outerHTML;
 }
 }
 
 //refreshes the HTML, before doing anything else
 div.innerHTML = html;
 
 if('function' === typeof lang_defs[i].patch)
 {
 var returned = lang_defs[i].patch.call( div );
 if('string' === typeof returned)
 {
 div.innerHTML = returned;
 }
 }
 }
 
 
 //only change at the end, to avoid unnecessary reflow
 element.className += ' highlight ' + lang;
 element.innerHTML = div.innerHTML;
 
 return true;
 };
 //default replace object
 f.default_replace = {'tag': 'span', 'text': '1ドル'};
 
 //all the languages will be added here
 f.langs = {};
 })(Function('return this')());//just be sure that we have the real window
//==========================================================
 // sql syntax highlight, anothed different file
 (function(window){
 if('function' === typeof window.highlight)
 {
 window.highlight.langs.sql=[
 {
 'class':'string',
 'match':/([bn]?"(?:[^"]|[\\"]")*"|[bn]?'(?:[^']|[\\']')*')(?=[\b\s\(\),;\$#\+\-\*\/]|$)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'comment',
 'match':/((?:\/\/|\-\-\s|#)[^\r\n]*|\/\*(?:[^*]|\*[^\/])*(?:\*\/|$))/g,
 'replace':window.highlight.default_replace,
 'patch':function(){
 return this.innerHTML.replace(
 /((?:\/\/|\-\-\s|#)[^\r\n]*|\/\*(?:[^*]|\*[^\/])*(?:\*\/|$))/g,
 '1ドル</span>'
 ).replace(//matches single-line comments
 /<span class="comment">((?:#|-- |\/\/)(?:.|<\/span><span class="[^"]+">([^<])<\/span>)*)([\r\n]|$)/g,
 function(_,part1,part2,part3){
 return '<span class="comment">'+
 //cleans up all spans
 ((part1||'')+(part2||'')).replace(/<\/?span(?: class="[^"]+")?>/g,'')+
 '</span>'+
 (part3||'');
 }
 ).replace(//matches multi-line comments
 /<span class="comment">(\/\*(?:[^*]|\*[^\/])+(?:\*\/(?:<\/span>)?|$))/g,
 function(_,part1){
 return '<span class="comment">'+
 //cleans up all spans
 ((part1||'')).replace(/<\/?span(?: class="[^"]+")?>/g,'')+
 '</span>';
 }
 );
 }
 },
 {
 /* 
 * numbers aren't that 'regular' and many edge-cases were left behind 
 * with the help of @MLM (http://stackoverflow.com/users/796832/mlm), 
 * we were able to make this work. 
 * he took over the regex and patched it all up, I did the replace string 
 */
 'match':/((?:^|\b|\(|\s|,))(?![a-z_]+)([+\-]?\d+(?:\.\d+)?(?:[eE]-?\d+)?)((?=$|\b|\s|\(|\)|,|;))/g,
 'replace':'1ドル<span class="number">2ドル</span>3ドル'
 },
 {
 'class':'name',
 'match':/(`[^`]+`)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'var',
 'match':/(@@?[a-z_][a-z_\d]*)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'keyword',
 //the keyword replace must have an aditional check (`(?!\()` after the name), due to the function replace()
 'match':/\b(accessible|add|all|alter|analyze|and|as|asc|asensitive|before|between|bigint|binary|blob|both|by|call|cascade|case|change|char|character|check|collate|column|condition|constraint|continue|convert|create|cross|current_date|current_time|current_timestamp|current_user|cursor|database|databases|day_hour|day_microsecond|day_minute|day_second|dec|decimal|declare|default|delayed|delete|desc|describe|deterministic|distinct|distinctrow|div|double|drop|dual|each|else|elseif|enclosed|escaped|exists|exit|explain|false|fetch|float|float4|float8|for|force|foreign|from|fulltext|generated|get|grant|group|having|high_priority|hour_microsecond|hour_minute|hour_second|if|ignore|in|index|infile|inner|inout|insensitive|insert|int|int1|int2|int3|int4|int8|integer|interval|into|io_after_gtids|io_before_gtids|is|iterate|join|key|keys|kill|leading|leave|left|like|limit|linear|lines|load|localtime|localtimestamp|lock|long|longblob|longtext|loop|low_priority|master_bind|master_ssl_verify_server_cert|match|maxvalue|mediumblob|mediumint|mediumtext|middleint|minute_microsecond|minute_second|mod|modifies|natural|nonblocking|not|no_write_to_binlog|null|numeric|on|optimize|optimizer_costs|option|optionally|or|order|out|outer|outfile|parse_gcol_expr|partition|precision|primary|procedure|purge|range|read|reads|read_write|real|references|regexp|release|rename|repeat|replace(?!\()|require|resignal|restrict|return|revoke|right|rlike|schema|schemas|second_microsecond|select|sensitive|separator|set|show|signal|smallint|spatial|specific|sql|sqlexception|sqlstate|sqlwarning|sql_big_result|sql_calc_found_rows|sql_small_result|ssl|starting|stored|straight_join|table|terminated|then|tinyblob|tinyint|tinytext|to|trailing|trigger|true|undo|union|unique|unlock|unsigned|update|usage|use|using|utc_date|utc_time|utc_timestamp|values|varbinary|varchar|varcharacter|varying|virtual|when|where|while|with|write|xor|year_month|zerofill)\b/gi,
 'replace':window.highlight.default_replace
 },
 {
 'class':'func',
 'match':/\b([a-z_][a-z_\d]*)\b(?=\()/gi,
 'replace':window.highlight.default_replace
 },
 {
 'class':'name',
 'match':/\b([a-z\_][a-z_\d]*)\b/gi,
 'replace':window.highlight.default_replace
 }
 ];
 }
 })(Function('return this')());
 //=========================================================
 // execution example:
 window.onload = function(){
 
 highlight(document.getElementsByTagName('pre')[0]);
 
 }
/*console theme, main file*/
.highlight, .highlight *{
 background:black;
 color:white;
 font-family:'Consolas',monospace;
 font-size:16px;
 word-wrap: break-word;
 white-space: pre;
}
/*sql style, different file*/
.highlight.sql .keyword{color:teal;}
.highlight.sql .string{color:red;}
.highlight.sql .func{color:purple;}
.highlight.sql .number{color:#0F0;}
.highlight.sql .name{color:olive;}
.highlight.sql .var{color:green;}
.highlight.sql .comment{color:gray;}
<pre data-lang="sql">
 
CREATE TABLE `shop` (
 article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
 dealer CHAR(20) DEFAULT '' NOT NULL,
 price DOUBLE(16,2) DEFAULT '0.00' NOT NULL,
 PRIMARY KEY(article, dealer));
INSERT INTO shop VALUES
 (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),
 (3,'C',1.69),(3,'D',-1.25),(4,'D',19.95);
 
#This is an example of sql a = 'b', 'c'
 
SELECT MAX(article) AS article FROM shop;
SELECT s1.article, s1.dealer, s1.price
FROM shop s1
LEFT JOIN shop s2 ON s1.price &lt; s2.price
WHERE s2.article IS NULL;
 
SELECT article, MAX(price) AS price
FROM shop
GROUP BY article;
 
SELECT article, dealer, price
FROM shop s1
WHERE price=(SELECT MAX(s2.price)
 FROM shop s2
 WHERE s1.article = s2.article);
SELECT @min_price:=MIN(price),@max_price:=MAX(price) FROM shop;
SELECT * FROM shop WHERE price=@min_price OR price=@max_price;
 
 /*
 
 a string =' ',
 
 */
select '1'#comment
 /*''*/ or 2;
</pre>

Also, the exception about the language being missing was adjusted.

Change 3:

You can now pass a set of elements (NodeList or HTMLCollection) and the elements will be highlighted.

The exceptions that are thrown will be handled differently, giving the other elements a chance.

(function(window){
 
 var f=window.highlight = function(element, lang){
 
 if(element instanceof NodeList || element instanceof HTMLCollection)
 {
 for(var i = 0, l = element.length; i<l; i++)
 {
 try
 {
 f( element[i], lang );
 }
 catch(e)
 {
 //we want to give a chance to all the other elements
 (console.error || console.log).call( console, e.message );
 }
 }
 return true;
 }
 
 if(!(element instanceof Element))
 {
 throw new TypeError( 'The 1st parameter must be an Element or NodeList' );
 }
 
 lang = lang || element.getAttribute('data-lang');
 
 if(!lang)
 {
 throw new TypeError( 'Missing language definition. Set the 2nd parameter or the attribute data-lang' );
 }
 
 var lang_defs = f.langs[lang];
 
 if(!lang_defs)
 {
 throw new TypeError( 'The language "' + lang + '" was not yet defined' );
 }
 
 //create a document fragment, to avoid reflow and increase performance
 var fragment = document.createDocumentFragment(),
 div = document.createElement('div');
 
 div.innerHTML = element.innerHTML;
 fragment.appendChild(div);
 
 for(var i = 0, l = lang_defs.length; i<l; i++)
 {
 var html = '';
 
 for(var j = 0, k = div.childNodes.length; j<k; j++)
 {
 if(div.childNodes[j].nodeType === 3)
 {
 html += div.childNodes[j].nodeValue
 .replace(
 lang_defs[i].match,
 /*shortcut to decide if the lang_defs[i].replace is one of those types
 *if so, passes it directly
 *otherwise, makes a string matching based on the object
 */
 {'string':1, 'function':1}[ typeof lang_defs[i].replace ]
 ? lang_defs[i].replace
 : '<' + lang_defs[i].replace.tag +
 ' class="' + lang_defs[i]['class'] + '">' +
 lang_defs[i].replace.text +
 '</' + lang_defs[i].replace.tag + '>'
 );
 }
 else
 {
 html += div.childNodes[j].outerHTML;
 }
 }
 
 //refreshes the HTML, before doing anything else
 div.innerHTML = html;
 
 if('function' === typeof lang_defs[i].patch)
 {
 var returned = lang_defs[i].patch.call( div );
 if('string' === typeof returned)
 {
 div.innerHTML = returned;
 }
 }
 }
 
 
 //only change at the end, to avoid unnecessary reflow
 element.className += ' highlight ' + lang;
 element.innerHTML = div.innerHTML;
 
 return true;
 };
 //default replace object
 f.default_replace = {'tag': 'span', 'text': '1ドル'};
 
 //all the languages will be added here
 f.langs = {};
})(Function('return this')());//just be sure that we have the real window
 (function(window){
 
 var f=window.highlight = function(element, lang){
 
 if(element instanceof NodeList || element instanceof HTMLCollection)
 {
 for(var i = 0, l = element.length; i<l; i++)
 {
 try
 {
 f( element[i], lang );
 }
 catch(e)
 {
 //we want to give a chance to all the other elements
 (console.error || console.log).call( console, e.message );
 }
 }
 return true;
 }
 
 if(!(element instanceof Element))
 {
 throw new TypeError( 'The 1st parameter must be an Element or NodeList' );
 }
 
 lang = lang || element.getAttribute('data-lang');
 
 if(!lang)
 {
 throw new TypeError( 'Missing language definition. Set the 2nd parameter or the attribute data-lang' );
 }
 
 var lang_defs = f.langs[lang];
 
 if(!lang_defs)
 {
 throw new TypeError( 'The language "' + lang + '" was not yet defined' );
 }
 
 //create a document fragment, to avoid reflow and increase performance
 var fragment = document.createDocumentFragment(),
 div = document.createElement('div');
 
 div.innerHTML = element.innerHTML;
 fragment.appendChild(div);
 
 for(var i = 0, l = lang_defs.length; i<l; i++)
 {
 var html = '';
 
 for(var j = 0, k = div.childNodes.length; j<k; j++)
 {
 if(div.childNodes[j].nodeType === 3)
 {
 html += div.childNodes[j].nodeValue
 .replace(
 lang_defs[i].match,
 /*shortcut to decide if the lang_defs[i].replace is one of those types
 *if so, passes it directly
 *otherwise, makes a string matching based on the object
 */
 {'string':1, 'function':1}[ typeof lang_defs[i].replace ]
 ? lang_defs[i].replace
 : '<' + lang_defs[i].replace.tag +
 ' class="' + lang_defs[i]['class'] + '">' +
 lang_defs[i].replace.text +
 '</' + lang_defs[i].replace.tag + '>'
 );
 }
 else
 {
 html += div.childNodes[j].outerHTML;
 }
 }
 
 //refreshes the HTML, before doing anything else
 div.innerHTML = html;
 
 if('function' === typeof lang_defs[i].patch)
 {
 var returned = lang_defs[i].patch.call( div );
 if('string' === typeof returned)
 {
 div.innerHTML = returned;
 }
 }
 }
 
 
 //only change at the end, to avoid unnecessary reflow
 element.className += ' highlight ' + lang;
 element.innerHTML = div.innerHTML;
 
 return true;
 };
 //default replace object
 f.default_replace = {'tag': 'span', 'text': '1ドル'};
 
 //all the languages will be added here
 f.langs = {};
 })(Function('return this')());//just be sure that we have the real window
//==========================================================
 // sql syntax highlight, anothed different file
 (function(window){
 if('function' === typeof window.highlight)
 {
 window.highlight.langs.sql=[
 {
 'class':'string',
 'match':/([bn]?"(?:[^"]|[\\"]")*"|[bn]?'(?:[^']|[\\']')*')(?=[\b\s\(\),;\$#\+\-\*\/]|$)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'comment',
 'match':/((?:\/\/|\-\-\s|#)[^\r\n]*|\/\*(?:[^*]|\*[^\/])*(?:\*\/|$))/g,
 'replace':window.highlight.default_replace,
 'patch':function(){
 return this.innerHTML.replace(
 /((?:\/\/|\-\-\s|#)[^\r\n]*|\/\*(?:[^*]|\*[^\/])*(?:\*\/|$))/g,
 '1ドル</span>'
 ).replace(//matches single-line comments
 /<span class="comment">((?:#|-- |\/\/)(?:.|<\/span><span class="[^"]+">([^<])<\/span>)*)([\r\n]|$)/g,
 function(_,part1,part2,part3){
 return '<span class="comment">'+
 //cleans up all spans
 ((part1||'')+(part2||'')).replace(/<\/?span(?: class="[^"]+")?>/g,'')+
 '</span>'+
 (part3||'');
 }
 ).replace(//matches multi-line comments
 /<span class="comment">(\/\*(?:[^*]|\*[^\/])+(?:\*\/(?:<\/span>)?|$))/g,
 function(_,part1){
 return '<span class="comment">'+
 //cleans up all spans
 ((part1||'')).replace(/<\/?span(?: class="[^"]+")?>/g,'')+
 '</span>';
 }
 );
 }
 },
 {
 /* 
 * numbers aren't that 'regular' and many edge-cases were left behind 
 * with the help of @MLM (http://stackoverflow.com/users/796832/mlm), 
 * we were able to make this work. 
 * he took over the regex and patched it all up, I did the replace string 
 */
 'match':/((?:^|\b|\(|\s|,))(?![a-z_]+)([+\-]?\d+(?:\.\d+)?(?:[eE]-?\d+)?)((?=$|\b|\s|\(|\)|,|;))/g,
 'replace':'1ドル<span class="number">2ドル</span>3ドル'
 },
 {
 'class':'name',
 'match':/(`[^`]+`)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'var',
 'match':/(@@?[a-z_][a-z_\d]*)/g,
 'replace':window.highlight.default_replace
 },
 {
 'class':'keyword',
 //the keyword replace must have an aditional check (`(?!\()` after the name), due to the function replace()
 'match':/\b(accessible|add|all|alter|analyze|and|as|asc|asensitive|before|between|bigint|binary|blob|both|by|call|cascade|case|change|char|character|check|collate|column|condition|constraint|continue|convert|create|cross|current_date|current_time|current_timestamp|current_user|cursor|database|databases|day_hour|day_microsecond|day_minute|day_second|dec|decimal|declare|default|delayed|delete|desc|describe|deterministic|distinct|distinctrow|div|double|drop|dual|each|else|elseif|enclosed|escaped|exists|exit|explain|false|fetch|float|float4|float8|for|force|foreign|from|fulltext|generated|get|grant|group|having|high_priority|hour_microsecond|hour_minute|hour_second|if|ignore|in|index|infile|inner|inout|insensitive|insert|int|int1|int2|int3|int4|int8|integer|interval|into|io_after_gtids|io_before_gtids|is|iterate|join|key|keys|kill|leading|leave|left|like|limit|linear|lines|load|localtime|localtimestamp|lock|long|longblob|longtext|loop|low_priority|master_bind|master_ssl_verify_server_cert|match|maxvalue|mediumblob|mediumint|mediumtext|middleint|minute_microsecond|minute_second|mod|modifies|natural|nonblocking|not|no_write_to_binlog|null|numeric|on|optimize|optimizer_costs|option|optionally|or|order|out|outer|outfile|parse_gcol_expr|partition|precision|primary|procedure|purge|range|read|reads|read_write|real|references|regexp|release|rename|repeat|replace(?!\()|require|resignal|restrict|return|revoke|right|rlike|schema|schemas|second_microsecond|select|sensitive|separator|set|show|signal|smallint|spatial|specific|sql|sqlexception|sqlstate|sqlwarning|sql_big_result|sql_calc_found_rows|sql_small_result|ssl|starting|stored|straight_join|table|terminated|then|tinyblob|tinyint|tinytext|to|trailing|trigger|true|undo|union|unique|unlock|unsigned|update|usage|use|using|utc_date|utc_time|utc_timestamp|values|varbinary|varchar|varcharacter|varying|virtual|when|where|while|with|write|xor|year_month|zerofill)\b/gi,
 'replace':window.highlight.default_replace
 },
 {
 'class':'func',
 'match':/\b([a-z_][a-z_\d]*)\b(?=\()/gi,
 'replace':window.highlight.default_replace
 },
 {
 'class':'name',
 'match':/\b([a-z\_][a-z_\d]*)\b/gi,
 'replace':window.highlight.default_replace
 }
 ];
 }
 })(Function('return this')());
 //=========================================================
 // execution example:
 window.onload = function(){
 
 highlight(document.getElementsByTagName('pre')[0]);
 
 }
/*console theme, main file*/
.highlight, .highlight *{
 background:black;
 color:white;
 font-family:'Consolas',monospace;
 font-size:16px;
 word-wrap: break-word;
 white-space: pre;
}
/*sql style, different file*/
.highlight.sql .keyword{color:teal;}
.highlight.sql .string{color:red;}
.highlight.sql .func{color:purple;}
.highlight.sql .number{color:#0F0;}
.highlight.sql .name{color:olive;}
.highlight.sql .var{color:green;}
.highlight.sql .comment{color:gray;}
<pre data-lang="sql">
 
CREATE TABLE `shop` (
 article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
 dealer CHAR(20) DEFAULT '' NOT NULL,
 price DOUBLE(16,2) DEFAULT '0.00' NOT NULL,
 PRIMARY KEY(article, dealer));
INSERT INTO shop VALUES
 (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),
 (3,'C',1.69),(3,'D',-1.25),(4,'D',19.95);
 
#This is an example of sql a = 'b', 'c'
 
SELECT MAX(article) AS article FROM shop;
SELECT s1.article, s1.dealer, s1.price
FROM shop s1
LEFT JOIN shop s2 ON s1.price &lt; s2.price
WHERE s2.article IS NULL;
 
SELECT article, MAX(price) AS price
FROM shop
GROUP BY article;
 
SELECT article, dealer, price
FROM shop s1
WHERE price=(SELECT MAX(s2.price)
 FROM shop s2
 WHERE s1.article = s2.article);
SELECT @min_price:=MIN(price),@max_price:=MAX(price) FROM shop;
SELECT * FROM shop WHERE price=@min_price OR price=@max_price;
 
 /*
 
 a string =' ',
 
 */
select '1'#comment
 /*''*/ or 2;
</pre>
Source Link
Ismael Miguel
  • 6.1k
  • 2
  • 23
  • 62
Loading
default

AltStyle によって変換されたページ (->オリジナル) /