diff options
| -rw-r--r-- | Makefile | 9 | ||||
| -rw-r--r-- | script/highlight.js | 29 | ||||
| -rw-r--r-- | script/prism.js | 428 | ||||
| -rw-r--r-- | script/prism_bash.js (renamed from script/ousia.js) | 19 | ||||
| -rw-r--r-- | style/prism.css | 137 | ||||
| -rw-r--r-- | style/style.less | 3 | ||||
| -rw-r--r-- | xsl/webpage.xsl | 9 | 
7 files changed, 622 insertions, 12 deletions
| @@ -15,7 +15,7 @@ TARGET_XML=$(SOURCE_OSML:.osml=.xml)  TARGET_HTML=$(SOURCE_OSML:.osml=.html)  # Builds the style and all webpages -all: style/style.css $(TARGET_XML) $(TARGET_HTML) +all: script/ousia.js style/style.css $(TARGET_XML) $(TARGET_HTML)  # Build the stylesheet using lessc  # On Fedora you can install lessc using the following commands (as root): @@ -24,6 +24,13 @@ all: style/style.css $(TARGET_XML) $(TARGET_HTML)  style/style.css: style/*.less  	lessc style/style.less style/style.css --clean-css="--s1" +# Build the JavaScript using uglifyjs +# On Fedora you can install uglifyjs using the following commands (as root): +#     yum install nodejs npm +#     npm install -g uglifyjs +script/ousia.js: script/prism.js script/prism_bash.js script/highlight.js +	uglifyjs script/prism.js script/prism_bash.js script/highlight.js > script/ousia.js +  # Compile all osml files to xml  %.xml: %.osml ontology/*.osml  	ousia -F xml -o $@ $< diff --git a/script/highlight.js b/script/highlight.js new file mode 100644 index 0000000..c50c172 --- /dev/null +++ b/script/highlight.js @@ -0,0 +1,29 @@ +// @license magnet:?xt=urn:btih:5305d91886084f776adcf57509a648432709a7c7&dn=x11.txt +/* + * Ousía Website JS + * + * (c) Andreas Stöckel, 2015 + * + * This work is licensed under the X11 (MIT) license. + * http://www.opensource.org/licenses/mit-license.php + */ +(function () { +	"use strict"; + +	/* Enable code highlighting (this will eventually be natively supported by +	   Ousía) */ +	document.addEventListener("DOMContentLoaded", function(event) { +		var codeBlocks = document.querySelectorAll("pre.code[data-lang]"); +		for (var i = 0; i < codeBlocks.length; i++) { +			var block = codeBlocks[i]; +			var lang = block.getAttribute("data-lang"); +			var text = block.textContent; +			if (lang in Prism.languages) { +				var res = Prism.highlight(text, Prism.languages[lang]); +				block.innerHTML = res; +			} +		} +	}); +})(); +// @license-end + diff --git a/script/prism.js b/script/prism.js new file mode 100644 index 0000000..fc62daa --- /dev/null +++ b/script/prism.js @@ -0,0 +1,428 @@ +/* http://prismjs.com/download.html?themes=prism */ +self = (typeof window !== 'undefined') +	? window   // if in browser +	: ( +		(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) +		? self // if in worker +		: {}   // if in node js +	); + +/** + * Prism: Lightweight, robust, elegant syntax highlighting + * MIT license http://www.opensource.org/licenses/mit-license.php/ + * @author Lea Verou http://lea.verou.me + */ + +var Prism = (function(){ + +// Private helper vars +var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i; + +var _ = self.Prism = { +	util: { +		encode: function (tokens) { +			if (tokens instanceof Token) { +				return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias); +			} else if (_.util.type(tokens) === 'Array') { +				return tokens.map(_.util.encode); +			} else { +				return tokens.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' '); +			} +		}, + +		type: function (o) { +			return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1]; +		}, + +		// Deep clone a language definition (e.g. to extend it) +		clone: function (o) { +			var type = _.util.type(o); + +			switch (type) { +				case 'Object': +					var clone = {}; + +					for (var key in o) { +						if (o.hasOwnProperty(key)) { +							clone[key] = _.util.clone(o[key]); +						} +					} + +					return clone; + +				case 'Array': +					return o.map(function(v) { return _.util.clone(v); }); +			} + +			return o; +		} +	}, + +	languages: { +		extend: function (id, redef) { +			var lang = _.util.clone(_.languages[id]); + +			for (var key in redef) { +				lang[key] = redef[key]; +			} + +			return lang; +		}, + +		/** +		 * Insert a token before another token in a language literal +		 * As this needs to recreate the object (we cannot actually insert before keys in object literals), +		 * we cannot just provide an object, we need anobject and a key. +		 * @param inside The key (or language id) of the parent +		 * @param before The key to insert before. If not provided, the function appends instead. +		 * @param insert Object with the key/value pairs to insert +		 * @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted. +		 */ +		insertBefore: function (inside, before, insert, root) { +			root = root || _.languages; +			var grammar = root[inside]; +			 +			if (arguments.length == 2) { +				insert = arguments[1]; +				 +				for (var newToken in insert) { +					if (insert.hasOwnProperty(newToken)) { +						grammar[newToken] = insert[newToken]; +					} +				} +				 +				return grammar; +			} +			 +			var ret = {}; + +			for (var token in grammar) { + +				if (grammar.hasOwnProperty(token)) { + +					if (token == before) { + +						for (var newToken in insert) { + +							if (insert.hasOwnProperty(newToken)) { +								ret[newToken] = insert[newToken]; +							} +						} +					} + +					ret[token] = grammar[token]; +				} +			} +			 +			// Update references in other language definitions +			_.languages.DFS(_.languages, function(key, value) { +				if (value === root[inside] && key != inside) { +					this[key] = ret; +				} +			}); + +			return root[inside] = ret; +		}, + +		// Traverse a language definition with Depth First Search +		DFS: function(o, callback, type) { +			for (var i in o) { +				if (o.hasOwnProperty(i)) { +					callback.call(o, i, o[i], type || i); + +					if (_.util.type(o[i]) === 'Object') { +						_.languages.DFS(o[i], callback); +					} +					else if (_.util.type(o[i]) === 'Array') { +						_.languages.DFS(o[i], callback, i); +					} +				} +			} +		} +	}, + +	highlightAll: function(async, callback) { +		var elements = document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'); + +		for (var i=0, element; element = elements[i++];) { +			_.highlightElement(element, async === true, callback); +		} +	}, + +	highlightElement: function(element, async, callback) { +		// Find language +		var language, grammar, parent = element; + +		while (parent && !lang.test(parent.className)) { +			parent = parent.parentNode; +		} + +		if (parent) { +			language = (parent.className.match(lang) || [,''])[1]; +			grammar = _.languages[language]; +		} + +		if (!grammar) { +			return; +		} + +		// Set language on the element, if not present +		element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; + +		// Set language on the parent, for styling +		parent = element.parentNode; + +		if (/pre/i.test(parent.nodeName)) { +			parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; +		} + +		var code = element.textContent; + +		if(!code) { +			return; +		} + +		code = code.replace(/^(?:\r?\n|\r)/,''); + +		var env = { +			element: element, +			language: language, +			grammar: grammar, +			code: code +		}; + +		_.hooks.run('before-highlight', env); + +		if (async && self.Worker) { +			var worker = new Worker(_.filename); + +			worker.onmessage = function(evt) { +				env.highlightedCode = Token.stringify(JSON.parse(evt.data), language); + +				_.hooks.run('before-insert', env); + +				env.element.innerHTML = env.highlightedCode; + +				callback && callback.call(env.element); +				_.hooks.run('after-highlight', env); +			}; + +			worker.postMessage(JSON.stringify({ +				language: env.language, +				code: env.code +			})); +		} +		else { +			env.highlightedCode = _.highlight(env.code, env.grammar, env.language); + +			_.hooks.run('before-insert', env); + +			env.element.innerHTML = env.highlightedCode; + +			callback && callback.call(element); + +			_.hooks.run('after-highlight', env); +		} +	}, + +	highlight: function (text, grammar, language) { +		var tokens = _.tokenize(text, grammar); +		return Token.stringify(_.util.encode(tokens), language); +	}, + +	tokenize: function(text, grammar, language) { +		var Token = _.Token; + +		var strarr = [text]; + +		var rest = grammar.rest; + +		if (rest) { +			for (var token in rest) { +				grammar[token] = rest[token]; +			} + +			delete grammar.rest; +		} + +		tokenloop: for (var token in grammar) { +			if(!grammar.hasOwnProperty(token) || !grammar[token]) { +				continue; +			} + +			var patterns = grammar[token]; +			patterns = (_.util.type(patterns) === "Array") ? patterns : [patterns]; + +			for (var j = 0; j < patterns.length; ++j) { +				var pattern = patterns[j], +					inside = pattern.inside, +					lookbehind = !!pattern.lookbehind, +					lookbehindLength = 0, +					alias = pattern.alias; + +				pattern = pattern.pattern || pattern; + +				for (var i=0; i<strarr.length; i++) { // Don’t cache length as it changes during the loop + +					var str = strarr[i]; + +					if (strarr.length > text.length) { +						// Something went terribly wrong, ABORT, ABORT! +						break tokenloop; +					} + +					if (str instanceof Token) { +						continue; +					} + +					pattern.lastIndex = 0; + +					var match = pattern.exec(str); + +					if (match) { +						if(lookbehind) { +							lookbehindLength = match[1].length; +						} + +						var from = match.index - 1 + lookbehindLength, +							match = match[0].slice(lookbehindLength), +							len = match.length, +							to = from + len, +							before = str.slice(0, from + 1), +							after = str.slice(to + 1); + +						var args = [i, 1]; + +						if (before) { +							args.push(before); +						} + +						var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias); + +						args.push(wrapped); + +						if (after) { +							args.push(after); +						} + +						Array.prototype.splice.apply(strarr, args); +					} +				} +			} +		} + +		return strarr; +	}, + +	hooks: { +		all: {}, + +		add: function (name, callback) { +			var hooks = _.hooks.all; + +			hooks[name] = hooks[name] || []; + +			hooks[name].push(callback); +		}, + +		run: function (name, env) { +			var callbacks = _.hooks.all[name]; + +			if (!callbacks || !callbacks.length) { +				return; +			} + +			for (var i=0, callback; callback = callbacks[i++];) { +				callback(env); +			} +		} +	} +}; + +var Token = _.Token = function(type, content, alias) { +	this.type = type; +	this.content = content; +	this.alias = alias; +}; + +Token.stringify = function(o, language, parent) { +	if (typeof o == 'string') { +		return o; +	} + +	if (_.util.type(o) === 'Array') { +		return o.map(function(element) { +			return Token.stringify(element, language, o); +		}).join(''); +	} + +	var env = { +		type: o.type, +		content: Token.stringify(o.content, language, parent), +		tag: 'span', +		classes: ['token', o.type], +		attributes: {}, +		language: language, +		parent: parent +	}; + +	if (env.type == 'comment') { +		env.attributes['spellcheck'] = 'true'; +	} + +	if (o.alias) { +		var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias]; +		Array.prototype.push.apply(env.classes, aliases); +	} + +	_.hooks.run('wrap', env); + +	var attributes = ''; + +	for (var name in env.attributes) { +		attributes += name + '="' + (env.attributes[name] || '') + '"'; +	} + +	return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + '</' + env.tag + '>'; + +}; + +if (!self.document) { +	if (!self.addEventListener) { +		// in Node.js +		return self.Prism; +	} + 	// In worker +	self.addEventListener('message', function(evt) { +		var message = JSON.parse(evt.data), +		    lang = message.language, +		    code = message.code; + +		self.postMessage(JSON.stringify(_.util.encode(_.tokenize(code, _.languages[lang])))); +		self.close(); +	}, false); + +	return self.Prism; +} + +// Get current script and highlight +var script = document.getElementsByTagName('script'); + +script = script[script.length - 1]; + +if (script) { +	_.filename = script.src; + +	if (document.addEventListener && !script.hasAttribute('data-manual')) { +		document.addEventListener('DOMContentLoaded', _.highlightAll); +	} +} + +return self.Prism; + +})(); + +if (typeof module !== 'undefined' && module.exports) { +	module.exports = Prism; +} +; diff --git a/script/ousia.js b/script/prism_bash.js index 0ef203a..24d5025 100644 --- a/script/ousia.js +++ b/script/prism_bash.js @@ -7,16 +7,15 @@   * This work is licensed under the X11 (MIT) license.   * http://www.opensource.org/licenses/mit-license.php   */ +  (function () { -	"use strict"; -	var header = document.querySelector("header"); -	window.addEventListener("scroll", function () { -		if (window.pageYOffset > 40) { -			header.className = "scrolled"; -		} else { -			header.className = ""; -		} -	}); +"use strict"; +Prism.languages.bash = { +	'comment': /#.*$/, +	'string': /("|')(\\\n|\\?.)*?\1/, +	'url': /http:\/\/[^\s]*/, +	'keyword': /(^| )(cd|mkdir|git|echo|clone|sudo|yum|apt-get|cmake|make|install)( |$)/ +};  })(); -// @license-end +// @license-end diff --git a/style/prism.css b/style/prism.css new file mode 100644 index 0000000..81b7382 --- /dev/null +++ b/style/prism.css @@ -0,0 +1,137 @@ +/* http://prismjs.com/download.html?themes=prism */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { +	color: black; +	text-shadow: 0 1px white; +	font-family: Consolas, Monaco, 'Andale Mono', monospace; +	direction: ltr; +	text-align: left; +	white-space: pre; +	word-spacing: normal; +	word-break: normal; +	line-height: 1.5; + +	-moz-tab-size: 4; +	-o-tab-size: 4; +	tab-size: 4; + +	-webkit-hyphens: none; +	-moz-hyphens: none; +	-ms-hyphens: none; +	hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { +	text-shadow: none; +	background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { +	text-shadow: none; +	background: #b3d4fc; +} + +@media print { +	code[class*="language-"], +	pre[class*="language-"] { +		text-shadow: none; +	} +} + +/* Code blocks */ +pre[class*="language-"] { +	padding: 1em; +	margin: .5em 0; +	overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { +	background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { +	padding: .1em; +	border-radius: .3em; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { +	color: slategray; +} + +.token.punctuation { +	color: #999; +} + +.namespace { +	opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol, +.token.deleted { +	color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { +	color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { +	color: #a67f59; +	background: hsla(0, 0%, 100%, .5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { +	color: #07a; +} + +.token.function { +	color: #DD4A68; +} + +.token.regex, +.token.important, +.token.variable { +	color: #e90; +} + +.token.important, +.token.bold { +	font-weight: bold; +} +.token.italic { +	font-style: italic; +} + +.token.entity { +	cursor: help; +} + diff --git a/style/style.less b/style/style.less index 3527378..f5603d0 100644 --- a/style/style.less +++ b/style/style.less @@ -13,6 +13,9 @@  @import "footer.less";  @import "header.less"; +/* Import the prism code highlighter stylesheet */ +@import "prism.css"; +  span.ipa {  	color: gray;  } diff --git a/xsl/webpage.xsl b/xsl/webpage.xsl index b66a594..fcb5d8a 100644 --- a/xsl/webpage.xsl +++ b/xsl/webpage.xsl @@ -79,6 +79,7 @@  						</p>  						</section>  					</footer> +					<script src="script/ousia.js"/>  				</body>  			</html>  	</xsl:template> @@ -225,7 +226,13 @@  	</xsl:template>  	<xsl:template match="webpage:code"> -		<pre class="code"> +		<pre> +			<xsl:attribute name="class">code</xsl:attribute> +			<xsl:if test="@lang != ''"> +				<xsl:attribute name="data-lang"> +					<xsl:value-of select="@lang"/> +				</xsl:attribute> +			</xsl:if>  			<xsl:apply-templates select="webpage:*"/>  		</pre>  	</xsl:template> | 
