├── README ├── applescript.js ├── code_highlighter.js ├── css.js ├── html.js ├── index.html ├── javascript.js ├── python.js ├── ruby.js ├── stylesetguide.html └── test.html /README: -------------------------------------------------------------------------------- 1 | CodeHighlighter 0.4 by Dan Webb 2 | ------------------------------- 3 | 4 | CodeHighlighter is a lightweight, unobstrusive and fully configurable script for displaying code examples highlighted in a way similar to the way many text editors highlight code. It weighs in at just under 4K, allows users to configure their own style sets so that you can highlight any language you like and is deployable simply by attaching it to a page with the script tag and adding class names as hooks. It should also play nicely with any other scripts on your page as it has a tiny footprint on the global namespace. 5 | 6 | Many thanks to Dean Edwards who's star-light behaviour inspired this. 7 | Deploying the script 8 | 9 | 1. Add a 7 | 8 | 9 | 10 | 11 | 102 | 103 | 104 | 105 |

CodeHighlighter 0.4 by Dan Webb

106 |

CodeHighlighter is a lightweight, unobstrusive and fully configurable script for displaying code examples highlighted in a way similar to the way many text editors highlight code. It weighs in at just under 4K, allows users to configure their own style sets so that you can highlight any language you like and is deployable simply by attaching it to a page with the script tag and adding class names as hooks. It should also play nicely with any other scripts on your page as it has a tiny footprint on the global namespace.

107 |

Many thanks to Dean Edwards who's star-light behaviour inspired this.

108 |

Deploying the script

109 |
    110 |
  1. Add a <script> tag for CodeHighlighter.js and a script tag for each of the code types you want to highlight on your page. At this time there are only very basic style sets for JavaScript, CSS and HTML. But it's easy to make your own for any language you like if you know regular expressions. Let me know if you do and I'll link to them.
  2. 111 |
  3. Add an appropriate class to each <code> element that contains code. 'javascript', 'ruby', 'css' or 'html' will do the trick.
  4. 112 |
  5. Define CSS styles for each code element, the script simply parses the code and wraps a <span> tag around each element with the appropriate class name. You just need to write CSS to style the code the way you want. No programming or weirdness required. See the source of this code as an example.
  6. 113 |
114 |

Testing

115 |

Known to work on:

116 | 122 |

Known to degrade well on:

123 | 127 |

Any other feedback for any other browser would be greatly apprieciated. Please email Dan Webb at dan[at]danwebb[dot]net. Have a look through the small examples below.

128 |

Creating your own style sets for other languages

129 |

Have a look at this guide to creating style sets.

130 |

Cheers,
Dan

131 |

Inline code

132 |

Hopefully, you should be able to put some code inline like this: document.write("bong") and hopefully it should work.

133 |

JavaScript Example

134 |
/*
135 | This script detects external links in a page
136 | and attaches a behaviour to them so they open
137 | in a external window.
138 | */
139 | 
140 | function initialiseLinks() {
141 |     if (document.getElementsByTagName) {
142 |         var links = document.getElementsByTagName("A");
143 |         for (var i = 0; i < links.length; i++) {
144 |             if (links[i].href.indexOf("http:")==0) {
145 |                 // if the links URL starts with http: then we assume it's an external link
146 |                 links[i].onclick = function() {
147 |                     window.open(this.href);
148 |                     return false; // stop normal link behaviour
149 |                 }
150 |             }
151 |         }
152 |     }
153 | }
154 | 
155 | window.onload = initialiseLinks();
156 |

CSS Example

157 |
.javascript  .comment {
158 | 	color : green; /* ffbgffg */
159 | }
160 | 
161 | .javascript  .string {
162 | 	color : maroon;
163 | }
164 | 
165 | .javascript  .keywords {
166 | 	font-weight : bold;
167 | }
168 | 
169 | .javascript  .global {
170 | 	color : blue;
171 | 	font-weight: bolder;
172 | }
173 | 
174 | .javascript  .brackets {
175 | 	color : Gray;
176 | }
177 | 
178 | .javascript  .thing {
179 | 	font-size : 10px;
180 | 	background : url(ghgfhfg gh f.rtjhf);
181 | }
182 |

HTML Example

183 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
184 | <html xmlns="http://www.w3.org/1999/xhtml">
185 | 	<head>
186 | 		<title>CodeHighlighter example</title>
187 | 		<!-- This is all you need to do to get CodeHighlighter working -->
188 | 		<script type="text/javascript" src="CodeHighlighter.js"> </script>
189 | 		<script type="text/javascript" src="html.js"> </script>
190 | 	</head>
191 | 	<body>
192 | 		<p>Put your pre tags here!</p>
193 | 	</body>
194 | </html>
195 | 196 |

Ruby Example

197 |
def login
198 |    if !@params[:key].nil? && @attendee = Attendee.find_by_hashkey(@params[:key])
199 |       # coming in with valid key
200 |       if !@attendee.password_set?
201 |         # no password yet, let them in
202 |         @session[:attendee] = @attendee
203 |         redirect_to :action => 'preferences', :id => @attendee.event.uri
204 |       else
205 |         @event = @attendee.event
206 |       end
207 |     else 
208 |       # if no key we need to know the event
209 |       @event = get_event_by_id_or_uri
210 |     end
211 |     
212 |     if @request.post?
213 |       # posted login details
214 |       if @attendee = Attendee.authenticate(@event, @params[:email], @params[:password])
215 |          @session[:attendee] = @attendee
216 |          redirect_to :action => 'preferences', :id => @event.uri
217 |       else
218 |         flash['notice'] = 'Login unsuccessful.'
219 |       end
220 |     end
221 |     
222 |     if @attendee.nil?
223 |       @email = ''
224 |     else
225 |       @email = @attendee.email
226 |     end
227 |   end
228 | 229 | 230 | -------------------------------------------------------------------------------- /javascript.js: -------------------------------------------------------------------------------- 1 | CodeHighlighter.addStyle("javascript",{ 2 | comment : { 3 | exp : /(\/\/[^\n]*(\n|$))|(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)/ 4 | }, 5 | brackets : { 6 | exp : /\(|\)/ 7 | }, 8 | string : { 9 | exp : /'[^'\\]*(\\.[^'\\]*)*'|"[^"\\]*(\\.[^"\\]*)*"/ 10 | }, 11 | keywords : { 12 | 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/ 13 | }, 14 | global : { 15 | exp : /\b(toString|valueOf|window|element|prototype|constructor|document|escape|unescape|parseInt|parseFloat|setTimeout|clearTimeout|setInterval|clearInterval|NaN|isNaN|Infinity)\b/ 16 | } 17 | }); -------------------------------------------------------------------------------- /python.js: -------------------------------------------------------------------------------- 1 | CodeHighlighter.addStyle("python",{ 2 | comment : { 3 | exp : /#[^\n]+/ 4 | }, 5 | brackets : { 6 | exp : /\(|\)/ 7 | }, 8 | string : { 9 | exp : /'[^'\\]*(\\.[^'\\]*)*'|"[^"\\]*(\\.[^"\\]*)*"|""".*"""/ 10 | }, 11 | keywords : { 12 | exp : /\b(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|as|None)\b/ 13 | } 14 | }); -------------------------------------------------------------------------------- /ruby.js: -------------------------------------------------------------------------------- 1 | CodeHighlighter.addStyle("ruby",{ 2 | comment : { 3 | exp : /#[^\n]+/ 4 | }, 5 | brackets : { 6 | exp : /\(|\)/ 7 | }, 8 | string : { 9 | exp : /'[^'\\]*(\\.[^'\\]*)*'|"[^"\\]*(\\.[^"\\]*)*"/ 10 | }, 11 | keywords : { 12 | exp : /\b(do|end|self|class|def|if|module|yield|then|else|for|until|unless|while|elsif|case|when|break|retry|redo|rescue|require|raise)\b/ 13 | }, 14 | /* Added by Shelly Fisher (shelly@agileevolved.com) */ 15 | symbol : { 16 | exp : /([^:])(:[A-Za-z0-9_!?]+)/ 17 | } 18 | }); -------------------------------------------------------------------------------- /stylesetguide.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Code Highlighter 0.2 - A Guide to creating style sets 6 | 7 | 8 | 58 | 59 | 60 | 61 |

CodeHighlighter 0.2

62 |

A guide to creating style sets

63 |

Style sets are written in JavaScript and are used by CodeHighlighter to match specific types of code and wrap them in, normally, a <span> tag with a specified class name. The stylesets themselves have a simple form but you may need to be a bit of a Regular Expressions badboy to create complex rules. Here's the style set for CSS:

64 |
CodeHighlighter.addStyle("css", {
65 | 	comment : {
66 | 		exp  : /\/\*[^*]*\*+([^\/][^*]*\*+)*\//
67 | 	},
68 | 	keywords : {
69 | 		exp  : /@\w[\w\s]*/
70 | 	},
71 | 	selectors : {
72 | 		exp  : "([\\w-:\\[.#][^{};>]*)(?={)"
73 | 	},
74 | 	properties : {
75 | 		exp  : "([\\w-]+)(?=\\s*:)"
76 | 	},
77 | 	units : {
78 | 		exp  : /([0-9])(em|en|px|%|pt)\b/,
79 | 		replacement : "$1<span class=\"$0\">$2</span>"
80 | 	},
81 | 	urls : {
82 | 		exp  : /url\([^\)]*\)/
83 | 	}
84 |  });
85 |

Use the CodeHighlighter.addStyle() method to add the style set rules. First define the class name that will trigger the style set, in this case 'css'. Any <pre> tag with the class "css" will use this style set.

86 |

The second argument to the method is an object containing the rules. Here's how a single rule goes together:

87 |
...
88 | classname : {
89 | 	exp  : /a regexp/, // or a reg exp as a string
90 | 	replacement : "$1<span class=\"$0\">$2</span>" // optional advanced replacement
91 | }, 
92 | ...
93 |

The property name is the class that will be applied to the matched text. The value of each property is another object containing the property exp which is mandatory and contains the RegExp (either in RegExp notation or as a string) required to match the text and a property replacement which is optional and only used for advanced replaces.

94 |

A simple replace (where no replacement property is specified) will simply wrap all of the matched text in a span tag if you need more control you can specify your own replacement rule using the replacement property. $0 will always output the class name while $1-$9 will match sub expressions in the regular way.

95 |

Note: If you want to use look aheads in your regular expressions go ahead but write them as a string. This prevents older browsers that do not support lookaheads from sprouting JavaScript errors.

96 |

Return to the examples page

97 | 98 | 99 | -------------------------------------------------------------------------------- /test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Code Highlighter 0.2 6 | 7 | 8 | 9 | 10 | 101 | 102 | 103 | 104 |

CodeHighlighter 0.2 by Dan Webb

105 |

CodeHighlighter is a lightweight, unobstrusive and fully configurable script for displaying code examples highlighted in a way similar to the way many text editors highlight code. It weighs in at just under 4K, allows users to configure their own style sets so that you can highlight any language you like and is deployable simply by attaching it to a page with the script tag and adding class names as hooks. It should also play nicely with any other scripts on your page as it has a tiny footprint on the global namespace.

106 |

Many thanks to Dean Edwards who's star-light behaviour inspired this.

107 |

Deploying the script

108 |
    109 |
  1. Add a <script> tag for CodeHighlighter.js and a script tag for each of the code types you want to highlight on your page. At this time there are only very basic style sets for JavaScript, CSS and HTML. But it's easy to make your own for any language you like if you know regular expressions. Let me know if you do and I'll link to them.
  2. 110 |
  3. Add an appropriate class to each <pre> element that contains code. 'javascript', 'css' or 'html' will do the trick.
  4. 111 |
  5. Define CSS styles for each code element, the script simply parses the code and wraps a <span> tag around each element with the appropriate class name. You just need to write CSS to style the code the way you want. No programming or weirdness required. See the source of this code as an example.
  6. 112 |
113 |

Testing

114 |

Known to work on:

115 | 121 |

Known to degrade well on:

122 | 125 |

Any other feedback for any other browser would be greatly apprieciated. Please email Dan Webb at dan[at]danwebb[dot]net. Have a look through the small examples below.

126 |

Creating your own style sets for other languages

127 |

Have a look at this guide to creating style sets.

128 |

Cheers,
Dan

129 |

Inline code

130 |

Hopefully, you should be able to put some code inline like this: document.write("bong") and hopefully it should work.

131 |

JavaScript Example

132 |
/*
133 | This script detects external links in a page
134 | and attaches a behaviour to them so they open
135 | in a external window.
136 | */
137 | 
138 | function initialiseLinks() {
139 |     if (document.getElementsByTagName) {
140 |         var links = document.getElementsByTagName("A");
141 |         for (var i = 0; i < links.length; i++) {
142 |             if (links[i].href.indexOf("http:")==0) {
143 |                 // if the links URL starts with http: then we assume it's an external link
144 |                 links[i].onclick = function() {
145 |                     window.open(this.href);
146 |                     return false; // stop normal link behaviour
147 |                 }
148 |             }
149 |         }
150 |     }
151 | }
152 | 
153 | window.onload = initialiseLinks();
154 |

CSS Example

155 |
.javascript  .comment {
156 | 	color : green; /* ffbgffg */
157 | }
158 | 
159 | .javascript  .string {
160 | 	color : maroon;
161 | }
162 | 
163 | .javascript  .keywords {
164 | 	font-weight : bold;
165 | }
166 | 
167 | .javascript  .global {
168 | 	color : blue;
169 | 	font-weight: bolder;
170 | }
171 | 
172 | .javascript  .brackets {
173 | 	color : Gray;
174 | }
175 | 
176 | .javascript  .thing {
177 | 	font-size : 10px;
178 | 	background : url(ghgfhfg gh f.rtjhf);
179 | }
180 |

HTML Example

181 |

182 | function suckerfish(type, tag, parentId) {
183 | 	if (window.attachEvent) {
184 | 		window.attachEvent("onload", function() {
185 | 			var sfEls = (parentId==null)?document.getElementsByTagName(tag):document.getElementById(parentId).getElementsByTagName(tag);
186 | 			type(sfEls);
187 | 		});
188 | 	}
189 | }
190 | 
191 | sfHover = function(sfEls) {
192 | 	for (var i=0; i<sfEls.length; i++) {
193 | 		sfEls[i].onmouseover=function() {
194 | 			this.className+=" sfhover";
195 | 		}
196 | 		sfEls[i].onmouseout=function() {
197 | 			this.className=this.className.replace(new RegExp(" sfhover\\b"), "");
198 | 		}
199 | 	}
200 | }
201 | 
202 | sfFocus = function(sfEls) {
203 | 	for (var i=0; i<sfEls.length; i++) {
204 | 		sfEls[i].onfocus=function() {
205 | 			this.className+=" sffocus";
206 | 		}
207 | 		sfEls[i].onblur=function() {
208 | 			this.className=this.className.replace(new RegExp(" sffocus\\b"), "");
209 | 		}
210 | 	}
211 | }
212 | 
213 | sfActive = function(sfEls) {
214 | 	for (var i=0; i<sfEls.length; i++) {
215 | 		sfEls[i].onmousedown=function() {
216 | 			this.className+=" sfactive";
217 | 		}
218 | 		sfEls[i].onmouseup=function() {
219 | 			this.className=this.className.replace(new RegExp(" sfactive\\b"), "");
220 | 		}
221 | 	}
222 | }
223 | 
224 | sfTarget = function(sfEls) {
225 | 	var aEls = document.getElementsByTagName("A");
226 | 	document.lastTarget = null;
227 | 	for (var i=0; i<sfEls.length; i++) {
228 | 		if (sfEls[i].id) {
229 | 			if (location.hash==("#" + sfEls[i].id)) {
230 | 				sfEls[i].className+=" sftarget";
231 | 				document.lastTarget=sfEls[i];
232 | 			}
233 | 			for (var j=0; j<aEls.length; j++) {
234 | 				if (aEls[j].hash==("#" + sfEls[i].id)) aEls[j].targetEl = sfEls[i];
235 | 				aEls[j].onclick = function() {
236 | 					if (document.lastTarget) document.lastTarget.className = document.lastTarget.className.replace(new RegExp(" sftarget\\b"), "");
237 | 					if (this.targetEl) this.targetEl.className+=" sftarget";
238 | 					document.lastTarget=this.targetEl;
239 | 					return true;
240 | 				}
241 | 			}
242 | 		}
243 | 	}
244 | }
245 | 246 | 247 | --------------------------------------------------------------------------------