Commit 92f446fa9dd8c70855aca83f3c0376925ad1caa8

Lea Verou 2012-07-16T18:56:40

Line linking

diff --git a/code.js b/code.js
index 3252f2d..1b6848b 100644
--- a/code.js
+++ b/code.js
@@ -29,7 +29,16 @@ document.body.addEventListener('contentreceived', function(evt) {
 		'svg': 'markup'
 	}[(evt.src.match(/\.(\w+)$/) || [,''])[1]];
 	
-	pre.className = 'prism language-' + language;
+	pre.className = 'prism';
 	
-	Prism.highlight(pre, true);
+	var code = document.createElement('code');
+	
+	code.className = 'lang-' + language;
+	
+	code.textContent = pre.textContent;
+	pre.textContent = '';
+	
+	pre.appendChild(code);
+	
+	Prism.highlight(code, true);
 });
\ No newline at end of file
diff --git a/examples.html b/examples.html
index dad43dc..7b53042 100644
--- a/examples.html
+++ b/examples.html
@@ -3,7 +3,7 @@
 <head>
 
 <meta charset="utf-8" />
-<title>Prism</title>
+<title>Examples ▲ Prism</title>
 <link rel="stylesheet" href="style.css" />
 <link rel="stylesheet" href="prism.css" data-noprefix />
 <script src="../prefixfree/prefixfree.min.js"></script>
diff --git a/plugins/line-highlight/index.html b/plugins/line-highlight/index.html
index 0c8afbd..dd5dca8 100644
--- a/plugins/line-highlight/index.html
+++ b/plugins/line-highlight/index.html
@@ -3,17 +3,18 @@
 <head>
 
 <meta charset="utf-8" />
-<title>Prism</title>
-<link rel="stylesheet" href="../../style.css" />
-<link rel="stylesheet" href="../../prism.css" data-noprefix />
-<link rel="stylesheet" href="prism-line-highlight.css" data-noprefix />
-<script src="../../../prefixfree/prefixfree.min.js"></script>
+<title>Line highlight ▲ Prism plugins</title>
+<base href="../.." />
+<link rel="stylesheet" href="style.css" />
+<link rel="stylesheet" href="prism.css" data-noprefix />
+<link rel="stylesheet" href="plugins/line-highlight/prism-line-highlight.css" data-noprefix />
+<script src="../prefixfree/prefixfree.min.js"></script>
 
 </head>
 <body>
 
 <header>
-	<h1><img src="../../logo.svg" alt="Prism" /> plugins</h1>
+	<h1><img src="logo.svg" alt="Prism" /> plugins</h1>
 
 	<h2>Line highlight plugin</h2>
 	<p>Highlights specific lines and/or line ranges.</p>
@@ -58,40 +59,24 @@
 	<h1>Examples</h1>
 	
 	<h2>Line 2</h2>
-	<pre class="prism" data-line="2"><code class="language-css">*
-{
-	color: red;
-}</code></pre>
+	<pre data-line="2" data-src="plugins/line-highlight/prism-line-highlight.js" id="play"></pre>
 	
-	<h2>Lines 1-2</h2>
-	<pre class="prism" data-line="1-2"><code class="language-css">*
-{
-	color: red;
-}</code></pre>
+	<h2>Lines 15-25</h2>
+	<pre data-line="15-25" data-src="plugins/line-highlight/prism-line-highlight.js"></pre>
 	
-	<h2>Line 1 and lines 3-4</h2>
-	<pre class="prism" data-line="1,3-4"><code class="language-css">*
-{
-	color: red;
-}</code></pre>
+	<h2>Line 1 and lines 3-4 and line 42</h2>
+	<pre data-line="1,3-4,42" data-src="plugins/line-highlight/prism-line-highlight.js"></pre>
 	
-	<h2>Line 1 and line 4</h2>
-	<pre class="prism" data-line="1,4"><code class="language-css">*
-{
-	color: red;
-}</code></pre>
-
-	<h2>Line 42, start from line 41</h2>
-	<pre class="prism" data-line="42" data-line-offset="40"><code class="language-css">*
-{
-	color: red;
-}</code></pre>
+	<h2>Line 43, starting from line 41</h2>
+	<pre data-line="43" data-line-offset="40" data-src="plugins/line-highlight/prism-line-highlight.js"></pre>
 </section>
 
 <footer data-src="templates/footer.html" data-type="text/html"></footer>
 
-<script src="../../prism.js"></script>
-<script src="prism-line-highlight.js"></script>
+<script src="prism.js"></script>
+<script src="utopia.js"></script>
+<script src="code.js"></script>
+<script src="plugins/line-highlight/prism-line-highlight.js"></script>
 
 </body>
 </html>
\ No newline at end of file
diff --git a/plugins/line-highlight/prism-line-highlight.css b/plugins/line-highlight/prism-line-highlight.css
index c1e478e..b18fa72 100644
--- a/plugins/line-highlight/prism-line-highlight.css
+++ b/plugins/line-highlight/prism-line-highlight.css
@@ -3,6 +3,10 @@ pre.prism[data-line] {
 	padding: 1em 0 1em 3em;
 }
 
+pre.prism[data-line] > code {
+	position: relative;
+}
+
 .line-highlight {
 	position: absolute;
 	left: 0;
diff --git a/plugins/line-highlight/prism-line-highlight.js b/plugins/line-highlight/prism-line-highlight.js
index a2ec9f8..cd45e9b 100644
--- a/plugins/line-highlight/prism-line-highlight.js
+++ b/plugins/line-highlight/prism-line-highlight.js
@@ -1,44 +1,97 @@
 (function(){
 
-if(!window.Prism || !window.getComputedStyle) {
+if(!window.Prism
+ || !window.addEventListener 
+ || !window.getComputedStyle
+ || !document.querySelectorAll) {
 	return;
 }
 
-var CRLF = crlf = /\r?\n|\r/g;
+function $$(expr, con) {
+	return Array.prototype.slice.call((con || document).querySelectorAll(expr));
+}
 
-Prism.hooks.add('after-highlight', function(env) {
-	var pre = /pre/i.test(env.element.nodeName)? env.element
-	          : /pre/i.test(env.element.parentNode.nodeName)? env.element.parentNode
-	          : null;
-	
-	if (!pre || !pre.hasAttribute('data-line')) {
-		return;
-	}
-	
-	var ranges = pre.getAttribute('data-line').replace(/\s+/g, '').split(',');
-	var offset = +pre.getAttribute('data-line-offset') || 0;
-	
-	for (var i=0, range; range=ranges[i++];) {
+var CRLF = crlf = /\r?\n|\r/g,
+    preTag = /pre/i;
+    
+function highlightLines(pre, lines, classes) {
+	var ranges = lines.replace(/\s+/g, '').split(','),
+	    offset = +pre.getAttribute('data-line-offset') || 0;
+	    
+	var cs = getComputedStyle(pre),
+	    lineHeight = parseFloat(cs.lineHeight);
+
+	for (var i=0, range; range = ranges[i++];) {
 		range = range.split('-');
-		
-		var start = +range[0], end = +range[1] || start;
+					
+		var start = +range[0],
+		    end = +range[1] || start;
 		
 		var line = document.createElement('div');
-		line.className = 'line-highlight';
+		
+		line.className = (classes || '') + ' line-highlight';
 		line.setAttribute('data-start', start);
 		
 		if(end > start) {
 			line.setAttribute('data-end', end);
 		}
-		
-		var lines = (env.code.match(CRLF) || []).length + 1,
-		    lineHeight = parseFloat(getComputedStyle(pre).height)/lines;
-
+	
 		line.style.height = (end - start + 1) * lineHeight + 'px';
 		line.style.top = (start - offset - 1) * lineHeight + 'px';
 		
 		pre.insertBefore(line, pre.firstChild);
 	}
+}
+
+function applyHash() {
+	var hash = location.hash.slice(1);
+	
+	// Remove pre-existing temporary lines
+	$$('.temporary.line-highlight').forEach(function (line) {
+		line.parentNode.removeChild(line);
+	});
+	
+	var range = (hash.match(/\.([\d,-]+)$/) || [,''])[1];
+	
+	if(!range || document.getElementById(hash)) {
+		return;
+	}
+	
+	var id = hash.slice(0, hash.lastIndexOf('.')),
+	    pre = document.getElementById(id);
+	    
+	if(!pre) {
+		return;
+	}
+
+	highlightLines(pre, range, 'temporary ');
+
+	document.querySelector('.temporary.line-highlight').scrollIntoView();
+}
+
+var fakeTimer = 0; // Hack to limit the number of times applyHash() runs
+
+Prism.hooks.add('after-highlight', function(env) {
+	clearTimeout(fakeTimer);
+	
+	var pre = preTag.test(env.element.nodeName)? env.element
+	        : preTag.test(env.element.parentNode.nodeName)? env.element.parentNode
+	        : null,
+	    lines = pre.getAttribute('data-line');
+	
+	if (!pre || !lines) {
+		return;
+	}
+	
+	$$('.line-highlight', pre).forEach(function (line) {
+		line.parentNode.removeChild(line);
+	});
+	
+	highlightLines(pre, lines);
+	
+	fakeTimer = setTimeout(applyHash, 1);
 });
 
+addEventListener('hashchange', applyHash);
+
 })();
\ No newline at end of file