Posted By

bitcrumb on 09/15/07


Tagged

javascript html code highlight unobtrusive highlighting


Versions (?)

Who likes this?

3 people have marked this snippet as a favorite

vali29
korzhik
zreedeecom


Unobtrusive Code Highlighter By Dan Webb


 / Published in: JavaScript
 

  1. /* Unobtrustive Code Highlighter By Dan Webb 11/2005 Version: 0.4 */
  2.  
  3. var CodeHighlighter = { styleSets : new Array };
  4.  
  5. CodeHighlighter.addStyle = function(name, rules) {
  6. if ([].push) this.styleSets.push({
  7. name : name,
  8. rules : rules,
  9. ignoreCase : arguments[2] || false
  10. })
  11.  
  12. function setEvent() {
  13. var old = window.onload;
  14.  
  15. if (typeof window.onload != 'function') {
  16. window.onload = function() { CodeHighlighter.init() }
  17. } else {
  18. window.onload = function() {
  19. oldonload();
  20. CodeHighlighter.init();
  21. }
  22. }
  23. }
  24.  
  25. if (this.styleSets.length==1) setEvent();
  26. }
  27.  
  28. CodeHighlighter.init = function() {
  29. if (!document.getElementsByTagName) return;
  30. if ("a".replace(/a/, function() {return "b"}) != "b") return;
  31.  
  32. var codeEls = document.getElementsByTagName("CODE");
  33. codeEls.filter = function(f) {
  34. var a = new Array;
  35. for (var i = 0; i < this.length; i++) if (f(this[i])) a[a.length] = this[i];
  36. return a;
  37. }
  38.  
  39. var rules = new Array;
  40. rules.toString = function() {
  41. var exps = new Array;
  42. for (var i = 0; i < this.length; i++) exps.push(this[i].exp);
  43. return exps.join("|");
  44. }
  45.  
  46. function addRule(className, rule) {
  47. var exp = (typeof rule.exp != "string")?String(rule.exp).substr(1, String(rule.exp).length-2):rule.exp;
  48. rules.push({
  49. className : className,
  50. exp : "(" + exp + ")",
  51. length : (exp.match(/(^|[^\\])\([^?]/g) || "").length + 1,
  52. replacement : rule.replacement || null
  53. });
  54. }
  55.  
  56. function parse(text, ignoreCase) {
  57. return text.replace(new RegExp(rules, (ignoreCase)?"gi":"g"), function() {
  58. var i = 0, j = 1, rule;
  59. while (rule = rules[i++]) {
  60. if (arguments[j]) {
  61. if (!rule.replacement) return "<span class=\"" + rule.className + "\">" + arguments[0] + "</span>";
  62. else {
  63. var str = rule.replacement.replace("$0", rule.className);
  64. for (var k = 1; k <= rule.length - 1; k++) str = str.replace("$" + k, arguments[j + k]);
  65. return str;
  66. }
  67. } else j+= rule.length;
  68. }
  69. });
  70. }
  71.  
  72. function highlightCode(styleSet) {
  73. var parsed;
  74. rules.length = 0;
  75.  
  76. var stylableEls = codeEls.filter(function(item) {return (item.className.indexOf(styleSet.name)>=0)});
  77.  
  78. for (var className in styleSet.rules) addRule(className, styleSet.rules[className]);
  79.  
  80.  
  81. for (var i = 0; i < stylableEls.length; i++) {
  82. if (/MSIE/.test(navigator.appVersion) && stylableEls[i].parentNode.nodeName == 'PRE') {
  83. stylableEls[i] = stylableEls[i].parentNode;
  84.  
  85. parsed = stylableEls[i].innerHTML.replace(/(<code[^>]*>)([^<]*)<\/code>/i, function() {
  86. return arguments[1] + parse(arguments[2], styleSet.ignoreCase) + "</code>"
  87. });
  88. parsed = parsed.replace(/\n( *)/g, function() {
  89. var spaces = "";
  90. for (var i = 0; i < arguments[1].length; i++) spaces+= "&nbsp;";
  91. return "\n" + spaces;
  92. });
  93. parsed = parsed.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;");
  94. parsed = parsed.replace(/\n(<\/\w+>)?/g, "<br />$1").replace(/<br \/>[\n\r\s]*<br \/>/g, "<p><br></p>");
  95.  
  96. } else parsed = parse(stylableEls[i].innerHTML, styleSet.ignoreCase);
  97.  
  98. stylableEls[i].innerHTML = parsed;
  99. }
  100. }
  101.  
  102. for (var i in this.styleSets) highlightCode(this.styleSets[i]);
  103. }
  104.  
  105.  
  106.  
  107. CodeHighlighter.addStyle("css", {
  108. ccomment : {
  109. exp : /\/\*[^*]*\*+([^\/][^*]*\*+)*\//
  110. },
  111. keyword : {
  112. exp : /@\w[\w\s]*/
  113. },
  114. selector : {
  115. exp : "([\\w-:\\[.#][^{};>]*)(?={)"
  116. },
  117. property : {
  118. exp : "([\\w-]+)(?=\\s*:)"
  119. },
  120. unit : {
  121. exp : /([0-9])(em|en|px|%|pt)\b/,
  122. replacement : "$1<span class=\"$0\">$2</span>"
  123. },
  124. url : {
  125. exp : /url\([^\)]*\)/
  126. }
  127. });
  128.  
  129. CodeHighlighter.addStyle("html", {
  130. ccomment : {
  131. exp: /&lt;!\s*(--([^-]|[
  132. ]|-[^-])*--\s*)&gt;/
  133. },
  134. tag : {
  135. exp: /(&lt;\/?)([a-zA-Z]+\s?)/,
  136. replacement: "$1<span class=\"$0\">$2</span>"
  137. },
  138. string : {
  139. exp : /'[^']*'|"[^"]*"/
  140. },
  141. attribute : {
  142. exp: /\b([a-zA-Z-:]+)(=)/,
  143. replacement: "<span class=\"$0\">$1</span>$2"
  144. },
  145. doctype : {
  146. exp: /&lt;!DOCTYPE([^&]|&[^g]|&g[^t])*&gt;/
  147. }
  148. });
  149.  
  150. CodeHighlighter.addStyle("javascript",{
  151. comment : {
  152. exp : /(\/\/[^\n]*\n)|(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)/
  153. },
  154. brackets : {
  155. exp : /\(|\)/
  156. },
  157. string : {
  158. exp : /'[^']*'|"[^"]*"/
  159. },
  160. keywords : {
  161. exp : /\b(arguments|break|case|continue|default|delete|do|else|false|for|function|if|in|instanceof|new|null|return|switch|this|true|typeof|var|void|while|with)\b/
  162. },
  163. global : {
  164. exp : /\b(toString|valueOf|window|element|prototype|constructor|document|escape|unescape|parseInt|parseFloat|setTimeout|clearTimeout|setInterval|clearInterval|NaN|isNaN|Infinity)\b/
  165. }
  166. });

Report this snippet  

You need to login to post a comment.