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>