diff --git a/Gemfile b/Gemfile
index 656941c1dc65bc7cefc58ca4eb460ebe856f0ec7..0bf06a373fb5805653b007eeba3eace2fb209265 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,7 +4,7 @@ gem 'rake'
 gem 'jekyll'
 
 group :default, :jekyll_plugins do
-  gem 'jekyll-scholar'
+  gem 'jekyll-scholar', :git => 'https://github.com/edgemaster/jekyll-scholar.git', :branch => 'master'
 end
 
 group :test do
diff --git a/Gemfile.lock b/Gemfile.lock
index 04c25dc512f3abc01492bbdc3d1817597c96d76c..69e28e1be975d736dbaa06b49c96623c761e4c20 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,3 +1,14 @@
+GIT
+  remote: https://github.com/edgemaster/jekyll-scholar.git
+  revision: e0d4f7a10964f1b878c833fb67b570330d14bca6
+  branch: master
+  specs:
+    jekyll-scholar (5.6.0)
+      bibtex-ruby (~> 4.0, >= 4.0.13)
+      citeproc-ruby (~> 1.0)
+      csl-styles (~> 1.0)
+      jekyll (~> 3.0)
+
 GEM
   remote: https://rubygems.org/
   specs:
@@ -45,11 +56,6 @@ GEM
       safe_yaml (~> 1.0)
     jekyll-sass-converter (1.4.0)
       sass (~> 3.4)
-    jekyll-scholar (5.6.0)
-      bibtex-ruby (~> 4.0, >= 4.0.13)
-      citeproc-ruby (~> 1.0)
-      csl-styles (~> 1.0)
-      jekyll (~> 3.0)
     jekyll-watch (1.3.1)
       listen (~> 3.0)
     json (1.8.3)
@@ -88,7 +94,7 @@ PLATFORMS
 DEPENDENCIES
   html-proofer
   jekyll
-  jekyll-scholar
+  jekyll-scholar!
   rake
 
 BUNDLED WITH
diff --git a/_config.yml b/_config.yml
index 4a42068a8e1ec7cf67ab2843497fa20f418cd2ba..30470539a7d9aa047f9733b6b38e16ea6c0dbd1b 100644
--- a/_config.yml
+++ b/_config.yml
@@ -35,5 +35,6 @@ scholar:
   sort_by: year
   order: descending
   group_order: descending
+  bibliography_group_tag: 'h3,h4,h5,h6'
 
   repository: publications
diff --git a/_includes/head.html b/_includes/head.html
index 7772857ba7872f10f89e64fb324894c07ba077bd..4f3adb4aaa27e4695d22eb19b820691c6d262f82 100644
--- a/_includes/head.html
+++ b/_includes/head.html
@@ -10,6 +10,7 @@
   <link rel="shortcut icon" href="{{ "/favicon.ico" | prepend: site.baseurl }}">
 
   {% include external-assets-css.html %}
-  <link rel="stylesheet" href="{{ "/css/blog.css" | prepend: site.baseurl }}">
-  <link rel="stylesheet" href="{{ "/css/syntax.css" | prepend: site.baseurl }}">
+  <link rel="stylesheet" href="{{ "/assets/blog.css" | prepend: site.baseurl }}">
+  <link rel="stylesheet" href="{{ "/assets/syntax.css" | prepend: site.baseurl }}">
+  {% if page.dataspy %}<link rel="stylesheet" href="{{ "/assets/fixed-sticky/fixedsticky.css" | prepend: site.baseurl }}">{% endif %}
 </head>
diff --git a/_layouts/default.html b/_layouts/default.html
index a2b09f968d81499ffd1a314f2469bce50d861b3d..0b68c110ea5331370fac31cf1fa624dc1d337755 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -1,12 +1,13 @@
 <!DOCTYPE html>
 <html lang="en">
   {% include head.html %}
-  <body>
+  <body {% if page.dataspy %}data-spy="scroll" data-target="{{ page.dataspy }}"{% endif %}>
     {% include header.html %}
     <div class="container">
       {{ content }}
     </div>
     {% include footer.html %}
     {% include external-assets-js.html %}
+    {% if page.dataspy %}<script src="{{ "/assets/fixed-sticky/fixedsticky.js" | prepend: site.baseurl }}"></script>{% endif %}
   </body>
 </html>
diff --git a/_layouts/publication.html b/_layouts/publication.html
index 82ac33f4b0920fb6f234706be264feac4fb69120..d2e7d2b6c083dd85b6e1bae93005840c241b75aa 100644
--- a/_layouts/publication.html
+++ b/_layouts/publication.html
@@ -52,4 +52,3 @@ menu: false
     <textarea class="form-control" rows="10">{{ page.entry.bibtex }}</textarea>
   </div>
 </div>
-
diff --git a/css/blog.css b/assets/blog.scss
similarity index 71%
rename from css/blog.css
rename to assets/blog.scss
index f868391a3bc3fba440cf7d2a1e03139073e45811..90ed04ba450317e322cf5bb0ff88ff226e3c771b 100644
--- a/css/blog.css
+++ b/assets/blog.scss
@@ -1,3 +1,5 @@
+---
+---
 /*
 The MIT License (MIT)
 
@@ -24,6 +26,10 @@ THE SOFTWARE.
 Originally sourced from: https://raw.githubusercontent.com/twbs/bootstrap/20261385eacd6e86a362a08d56b4b4241ef248df/docs/examples/blog/blog.css
 */
 
+/* Variables */
+$primary_colour: #428bca;
+$highlight_colour: #cdddeb;
+
 /*
  * Globals
  */
@@ -37,6 +43,7 @@ Originally sourced from: https://raw.githubusercontent.com/twbs/bootstrap/202613
 body {
   font-family: Georgia, "Times New Roman", Times, serif;
   color: #555;
+  position: relative;
 }
 
 h1, .h1,
@@ -66,42 +73,77 @@ h6, .h6 {
 
 .site-masthead {
   margin-bottom: 3rem;
-  background-color: #428bca;
+  background-color: $primary_colour;
   -webkit-box-shadow: inset 0 -.1rem .25rem rgba(0,0,0,.2);
           box-shadow: inset 0 -.1rem .25rem rgba(0,0,0,.2);
-}
 
-/* Nav links */
-.nav-link {
-  position: relative;
-  padding: 1rem;
-  font-weight: 500;
-  color: #cdddeb;
-}
-.nav-link:hover,
-.nav-link:focus {
-  color: #fff;
-  background-color: transparent;
-}
+  /* Nav links */
+  .nav-link {
+    position: relative;
+    padding: 1rem;
+    font-weight: 500;
+    color: $highlight_colour;
+  }
+  .nav-link:hover,
+  .nav-link:focus {
+    color: #fff;
+    background-color: transparent;
+  }
 
-/* Active state gets a caret at the bottom */
-.nav-link.active {
-  color: #fff;
+  /* Active state gets a caret at the bottom */
+  .nav-link.active {
+    color: #fff;
+  }
+  .nav-link.active:after {
+    position: absolute;
+    bottom: 0;
+    left: 50%;
+    width: 0;
+    height: 0;
+    margin-left: -.3rem;
+    vertical-align: middle;
+    content: "";
+    border-right: .3rem solid transparent;
+    border-bottom: .3rem solid;
+    border-left: .3rem solid transparent;
+  }
 }
-.nav-link.active:after {
-  position: absolute;
-  bottom: 0;
-  left: 50%;
-  width: 0;
-  height: 0;
-  margin-left: -.3rem;
-  vertical-align: middle;
-  content: "";
-  border-right: .3rem solid transparent;
-  border-bottom: .3rem solid;
-  border-left: .3rem solid transparent;
+
+.stickyrow {
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display:         flex;
 }
 
+.sidenav {
+  .nav-item {
+    padding: 0px;
+  }
+
+  .nav-item.active {
+    background: white;
+  }
+
+  .nav-item > a {
+    display: block;
+    padding: 0.75rem 1.25rem;
+    border-width: 0 1px;
+    border-style: solid;
+    border-color: transparent;
+  }
+
+  .nav-item > a:hover {
+    background: $highlight_colour;
+    border-color: $primary_colour;
+  }
+
+  .nav-item.active > a {
+    border-width: 0 1px;
+    border-color: $primary_colour;
+    border-style: solid;
+  }
+}
 
 /*
  * Blog name and description
diff --git a/assets/fixed-sticky/LICENSE b/assets/fixed-sticky/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..206ca837f3e05bda368c3a801b9488312c7400d3
--- /dev/null
+++ b/assets/fixed-sticky/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 Filament Group
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/assets/fixed-sticky/fixedsticky.css b/assets/fixed-sticky/fixedsticky.css
new file mode 100644
index 0000000000000000000000000000000000000000..b7947d57116b9916ee5a7e2132128d93a035dff2
--- /dev/null
+++ b/assets/fixed-sticky/fixedsticky.css
@@ -0,0 +1,23 @@
+.fixedsticky {
+	position: -webkit-sticky;
+	position: -moz-sticky;
+	position: -ms-sticky;
+	position: -o-sticky;
+	position: sticky;
+        top: 10px;
+}
+/* When position: sticky is supported but native behavior is ignored */
+.fixedsticky-withoutfixedfixed .fixedsticky-off,
+.fixed-supported .fixedsticky-off {
+	position: static;
+}
+.fixedsticky-withoutfixedfixed .fixedsticky-on,
+.fixed-supported .fixedsticky-on {
+	position: fixed;
+}
+.fixedsticky-dummy {
+	display: none;
+}
+.fixedsticky-on + .fixedsticky-dummy {
+	display: block;
+}
diff --git a/assets/fixed-sticky/fixedsticky.js b/assets/fixed-sticky/fixedsticky.js
new file mode 100644
index 0000000000000000000000000000000000000000..27de0ce2e3a72919309bf4366a70749b6dfdda75
--- /dev/null
+++ b/assets/fixed-sticky/fixedsticky.js
@@ -0,0 +1,193 @@
+;(function( win, $ ) {
+
+	function featureTest( property, value, noPrefixes ) {
+		// Thanks Modernizr! https://github.com/phistuck/Modernizr/commit/3fb7217f5f8274e2f11fe6cfeda7cfaf9948a1f5
+		var prop = property + ':',
+			el = document.createElement( 'test' ),
+			mStyle = el.style;
+
+		if( !noPrefixes ) {
+			mStyle.cssText = prop + [ '-webkit-', '-moz-', '-ms-', '-o-', '' ].join( value + ';' + prop ) + value + ';';
+		} else {
+			mStyle.cssText = prop + value;
+		}
+		return mStyle[ property ].indexOf( value ) !== -1;
+	}
+
+	function getPx( unit ) {
+		return parseInt( unit, 10 ) || 0;
+	}
+
+	var uniqueIdCounter = 0;
+
+	var S = {
+		classes: {
+			plugin: 'fixedsticky',
+			active: 'fixedsticky-on',
+			inactive: 'fixedsticky-off',
+			clone: 'fixedsticky-dummy',
+			withoutFixedFixed: 'fixedsticky-withoutfixedfixed'
+		},
+		keys: {
+			offset: 'fixedStickyOffset',
+			position: 'fixedStickyPosition',
+			id: 'fixedStickyId'
+		},
+		tests: {
+			sticky: featureTest( 'position', 'sticky' ),
+			fixed: featureTest( 'position', 'fixed', true )
+		},
+		// Thanks jQuery!
+		getScrollTop: function() {
+			var prop = 'pageYOffset',
+				method = 'scrollTop';
+			return win ? (prop in win) ? win[ prop ] :
+				win.document.documentElement[ method ] :
+				win.document.body[ method ];
+		},
+		bypass: function() {
+			// Check native sticky, check fixed and if fixed-fixed is also included on the page and is supported
+			return ( S.tests.sticky && !S.optOut ) ||
+				!S.tests.fixed ||
+				win.FixedFixed && !$( win.document.documentElement ).hasClass( 'fixed-supported' );
+		},
+		update: function( el ) {
+			if( !el.offsetWidth ) { return; }
+
+			var $el = $( el ),
+				height = $el.outerHeight(),
+				initialOffset = $el.data( S.keys.offset ),
+				scroll = S.getScrollTop(),
+				isAlreadyOn = $el.is( '.' + S.classes.active ),
+				toggle = function( turnOn ) {
+					$el[ turnOn ? 'addClass' : 'removeClass' ]( S.classes.active )
+						[ !turnOn ? 'addClass' : 'removeClass' ]( S.classes.inactive );
+				},
+				viewportHeight = $( window ).height(),
+				position = $el.data( S.keys.position ),
+				skipSettingToFixed,
+				elTop,
+				elBottom,
+				$parent = $el.parent(),
+				parentOffset = $parent.offset().top,
+				parentHeight = $parent.outerHeight();
+
+			if( initialOffset === undefined ) {
+				initialOffset = $el.offset().top;
+				$el.data( S.keys.offset, initialOffset );
+				$el.after( $( '<div>' ).addClass( S.classes.clone ).height( height ) );
+			}
+
+			if( !position ) {
+				// Some browsers require fixed/absolute to report accurate top/left values.
+				skipSettingToFixed = $el.css( 'top' ) !== 'auto' || $el.css( 'bottom' ) !== 'auto';
+
+				if( !skipSettingToFixed ) {
+					$el.css( 'position', 'fixed' );
+				}
+
+				position = {
+					top: $el.css( 'top' ) !== 'auto',
+					bottom: $el.css( 'bottom' ) !== 'auto'
+				};
+
+				if( !skipSettingToFixed ) {
+					$el.css( 'position', '' );
+				}
+
+				$el.data( S.keys.position, position );
+			}
+
+			function isFixedToTop() {
+				var offsetTop = scroll + elTop;
+
+				// Initial Offset Top
+				return initialOffset < offsetTop &&
+					// Container Bottom
+					offsetTop + height <= parentOffset + parentHeight;
+			}
+
+			function isFixedToBottom() {
+				// Initial Offset Top + Height
+				return initialOffset + ( height || 0 ) > scroll + viewportHeight - elBottom &&
+					// Container Top
+					scroll + viewportHeight - elBottom >= parentOffset + ( height || 0 );
+			}
+
+			elTop = getPx( $el.css( 'top' ) );
+			elBottom = getPx( $el.css( 'bottom' ) );
+
+			if( position.top && isFixedToTop() || position.bottom && isFixedToBottom() ) {
+				if( !isAlreadyOn ) {
+					toggle( true );
+				}
+			} else {
+				if( isAlreadyOn ) {
+					toggle( false );
+				}
+			}
+		},
+		destroy: function( el ) {
+			var $el = $( el );
+			if (S.bypass()) {
+				return $el;
+			}
+
+			return $el.each(function() {
+				var $this = $( this );
+				var id = $this.data( S.keys.id );
+				$( win ).unbind( '.fixedsticky' + id );
+
+				$this
+					.removeData( [ S.keys.offset, S.keys.position, S.keys.id ] )
+					.removeClass( S.classes.active )
+					.removeClass( S.classes.inactive )
+					.next( '.' + S.classes.clone ).remove();
+			});
+		},
+		init: function( el ) {
+			var $el = $( el );
+
+			if( S.bypass() ) {
+				return $el;
+			}
+
+			return $el.each(function() {
+				var _this = this;
+				var id = uniqueIdCounter++;
+				$( this ).data( S.keys.id, id );
+
+				$( win ).bind( 'scroll.fixedsticky' + id, function() {
+					S.update( _this );
+				}).trigger( 'scroll.fixedsticky' + id );
+
+				$( win ).bind( 'resize.fixedsticky' + id , function() {
+					if( $el.is( '.' + S.classes.active ) ) {
+						S.update( _this );
+					}
+				});
+			});
+		}
+	};
+
+	win.FixedSticky = S;
+
+	// Plugin
+	$.fn.fixedsticky = function( method ) {
+		if ( typeof S[ method ] === 'function') {
+			return S[ method ].call( S, this);
+		} else if ( typeof method === 'object' || ! method ) {
+			return S.init.call( S, this );
+		} else {
+			throw new Error( 'Method `' +  method + '` does not exist on jQuery.fixedsticky' );
+		}
+	};
+
+	// Add fallback when fixed-fixed is not available.
+	if( !win.FixedFixed ) {
+		$( win.document.documentElement ).addClass( S.classes.withoutFixedFixed );
+	}
+
+})( window, jQuery );
+
+$('.fixedsticky').fixedsticky()
diff --git a/css/syntax.css b/assets/syntax.css
similarity index 100%
rename from css/syntax.css
rename to assets/syntax.css
diff --git a/publications/index.md b/publications/index.md
index ded3e68350269db859dc5e5146bac35f25f63c3e..083a94b0e63f1bbc7da78a59c5acba32d6eee11f 100644
--- a/publications/index.md
+++ b/publications/index.md
@@ -1,5 +1,15 @@
 ---
 title: Publications
+dataspy: "#sidenav"
 ---
-
-{% bibliography -g year %}
+<div class="row stickyrow">
+  <div class="col-sm-9">
+    {% bibliography -g year %}
+  </div>
+  <div class="col-sm-3">
+    <nav class="sidenav fixedsticky" id="sidenav"><ul class="nav list-group">
+      {% for group in page.bibliography_groups %}<li class="nav-item list-group-item"><a href="#{{group[0]}}" class="nav-link">{{group[0]}}</a></li>
+{% endfor %}
+    </ul></nav>
+  </div>
+</div>