diff options
Diffstat (limited to '')
29 files changed, 520 insertions, 117 deletions
diff --git a/.themes/classic/sass/base/_layout.scss b/.themes/classic/sass/base/_layout.scss index ef47279a..4a3c780f 100644 --- a/.themes/classic/sass/base/_layout.scss +++ b/.themes/classic/sass/base/_layout.scss @@ -75,6 +75,15 @@ aside[role=sidebar] { @extend .group; } +.flex-content { max-width: 100%; height: auto; } + +.basic-alignment { + &.left { float: left; margin-right: 1.5em; } + &.right { float: right; margin-left: 1.5em; } + &.center { display:block; margin: 0 auto 1.5em; } + &.left, &.right { margin-bottom: .8em; } +} + .toggle-sidebar { &, .no-sidebar & { display: none; }} body.sidebar-footer { @@ -103,7 +112,7 @@ body.sidebar-footer { @extend .group; margin-right: $sidebar-width-medium; position: relative; - .no-sidebar & { margin-right: 0; } + .no-sidebar & { margin-right: 0; border-right: 0; } .collapse-sidebar & { margin-right: 20px; } > div, > article { padding-top: $pad-medium/2; diff --git a/.themes/classic/sass/base/_utilities.scss b/.themes/classic/sass/base/_utilities.scss index 8b718cdc..2d49e659 100644 --- a/.themes/classic/sass/base/_utilities.scss +++ b/.themes/classic/sass/base/_utilities.scss @@ -5,6 +5,13 @@ height: image-height($img); } +@mixin shadow-box($border: #fff .5em solid, $shadow: rgba(#000, .15) 0 1px 4px, $border-radius: .3em) { + @include border-radius($border-radius); + @include box-shadow($shadow); + @include box-sizing(border-box); + border: $border; +} + @mixin selection($bg, $color: inherit, $text-shadow: none){ * { &::-moz-selection { background: $bg; color: $color; text-shadow: $text-shadow; } diff --git a/.themes/classic/sass/partials/_blog.scss b/.themes/classic/sass/partials/_blog.scss index 3416347b..558f0a22 100644 --- a/.themes/classic/sass/partials/_blog.scss +++ b/.themes/classic/sass/partials/_blog.scss @@ -44,19 +44,9 @@ article { line-height: 1.3em; } img, video, .flash-video { - max-width: 100%; - height: auto; - border: .5em solid #fff; - @include border-radius(.3em); - @include box-shadow(rgba(#000, .15) 0 1px 4px); - @include box-sizing(border-box); - display: block; - } - img { - &.left { float: left; margin-right: 1.5em; } - &.right { float: right; margin-left: 1.5em; } - &.center { margin: 0 auto 1.5em; } - &.left, &.right { margin-bottom: .8em; } + @extend .flex-content; + @extend .basic-alignment; + @include shadow-box; } video, .flash-video { margin: 0 auto 1.5em; } video { display: block; width: 100%; } diff --git a/.themes/classic/sass/partials/_syntax.scss b/.themes/classic/sass/partials/_syntax.scss index 7e8ed8d5..25e8d329 100644 --- a/.themes/classic/sass/partials/_syntax.scss +++ b/.themes/classic/sass/partials/_syntax.scss @@ -177,7 +177,7 @@ li code { .s1 { color: $solar-cyan !important; } /* Literal.String.Single */ //.ss { color: #990073 } /* Literal.String.Symbol */ //.il { color: #009999 } /* Literal.Number.Integer.Long */ - div { .gd, .gd .x, .gi, .gi .x { display: block; }} + div { .gd, .gd .x, .gi, .gi .x { display: inline-block; width: 100%; }} } .highlight, .gist-highlight { diff --git a/.themes/classic/sass/partials/sidebar/_base.scss b/.themes/classic/sass/partials/sidebar/_base.scss index 08f04d23..a0d1c09e 100644 --- a/.themes/classic/sass/partials/sidebar/_base.scss +++ b/.themes/classic/sass/partials/sidebar/_base.scss @@ -20,6 +20,11 @@ aside[role=sidebar] { } } } + img { + @extend .flex-content; + @extend .basic-alignment; + @include shadow-box($border: #fff .3em solid); + } ul { margin-bottom: 0.5em; margin-left: 0; diff --git a/.themes/classic/source/_includes/archive_post.html b/.themes/classic/source/_includes/archive_post.html index b667b88b..fef3328e 100644 --- a/.themes/classic/source/_includes/archive_post.html +++ b/.themes/classic/source/_includes/archive_post.html @@ -1,6 +1,6 @@ {% capture category %}{{ post.categories | size }}{% endcapture %} <h1><a href="{{ root_url }}{{ post.url }}">{{post.title}}</a></h1> -<time datetime="{{ post.date | datetime }}" pubdate>{{ post.date | date: "<span class='month'>%b</span> <span class='day'>%d</span> <span class='year'>%Y</span>"}}</time> +<time datetime="{{ post.date | datetime | date_to_xmlschema }}" pubdate>{{ post.date | date: "<span class='month'>%b</span> <span class='day'>%d</span> <span class='year'>%Y</span>"}}</time> {% if category != '0' %} <footer> <span class="categories">posted in {{ post.categories | category_links }}</span> diff --git a/.themes/classic/source/_includes/article.html b/.themes/classic/source/_includes/article.html index b561fbc7..5cd6fda1 100644 --- a/.themes/classic/source/_includes/article.html +++ b/.themes/classic/source/_includes/article.html @@ -6,7 +6,7 @@ <h1 class="entry-title">{{ page.title | titlecase }}</h1> {% endif %} {% unless page.meta == false %} - <p class="meta">{% include post/date.html %}</p> + <p class="meta">{% include post/date.html %}{{ time }}</p> {% endunless %} </header> {% endunless %} diff --git a/.themes/classic/source/_includes/asides/github.html b/.themes/classic/source/_includes/asides/github.html new file mode 100644 index 00000000..935ccff0 --- /dev/null +++ b/.themes/classic/source/_includes/asides/github.html @@ -0,0 +1,30 @@ +{% if site.github_user %} +<section> + <h1>Github Repos</h1> + <ul id="gh_repos"> + <li class="loading">Status updating...</li> + </ul> + {% if site.github_show_profile_link %} + <a href="https://github.com/{{site.github_user}}">@{{site.github_user}}</a> on Github + {% endif %} + <script type="text/javascript"> + $.domReady(function(){ + if (!window.jXHR){ + var jxhr = document.createElement('script'); + jxhr.type = 'text/javascript'; + jxhr.src = '{{ root_url}}/javascripts/libs/jXHR.js'; + var s = document.getElementsByTagName('script')[0]; + s.parentNode.insertBefore(jxhr, s); + } + + github.showRepos({ + user: '{{site.github_user}}', + count: {{site.github_repo_count}}, + skip_forks: {{site.github_skip_forks}}, + target: '#gh_repos' + }); + }); + </script> + <script src="{{ root_url }}/javascripts/github.js" type="text/javascript"> </script> +</section> +{% endif %} diff --git a/.themes/classic/source/_includes/head.html b/.themes/classic/source/_includes/head.html index d6a6735b..d1741120 100644 --- a/.themes/classic/source/_includes/head.html +++ b/.themes/classic/source/_includes/head.html @@ -4,7 +4,7 @@ <!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]--> <head> <meta charset="utf-8"> - <title>{{site.title}}{% if page.title %}: {{page.title}}{% endif %}</title> + <title>{% if page.title %}{{page.title}} - {% endif %}{{site.title}}</title> <meta name="author" content="{{site.author}}"> {% if page.description %} <meta name="description" content="{{page.description}}"/> @@ -26,8 +26,5 @@ <script src="http://s3.amazonaws.com/ender-js/jeesh.min.js"></script> <script src="{{ root_url }}/javascripts/octopress.js" type="text/javascript"></script> <link href="{{ site.subscribe_rss }}" rel="alternate" title="{{site.title}}" type="application/atom+xml"/> - {% include google_analytics.html %} - {% include google_plus_one.html %} - {% include twitter_sharing.html %} {% include custom/head.html %} </head> diff --git a/.themes/classic/source/_includes/post/date.html b/.themes/classic/source/_includes/post/date.html index f1ed4815..dbfa67ae 100644 --- a/.themes/classic/source/_includes/post/date.html +++ b/.themes/classic/source/_includes/post/date.html @@ -2,9 +2,11 @@ {% capture has_date %}{{ date | size }}{% endcapture %} {% capture updated %}{{ page.updated }}{{ post.updated }}{% endcapture %} {% capture was_updated %}{{ updated | size }}{% endcapture %} + {% if has_date != '0' %} -<time datetime="{{ date | datetime }}" pubdate {% if updated %} updated {% endif %}>{{ date | ordinalize }}</time> + {% capture time %}<time datetime="{{ date | datetime | date_to_xmlschema }}" pubdate {% if updated %} data-updated="true" {% endif %}>{{ date | ordinalize }}</time>{% endcapture %} {% endif %} + {% if was_updated != '0' %} -<time class="updated" datetime="{{ updated | datetime }}"></time> -{% endif %} + {% capture updated %}<time class="updated" datetime="{{ updated | datetime | date_to_xmlschema }}">Updated {{ updated | ordinalize }}</time>{% endcapture %} +{% else %}{% assign updated = false %}{% endif %} diff --git a/.themes/classic/source/_includes/post/sharing.html b/.themes/classic/source/_includes/post/sharing.html index 7b074af5..f0f9b9db 100644 --- a/.themes/classic/source/_includes/post/sharing.html +++ b/.themes/classic/source/_includes/post/sharing.html @@ -3,6 +3,6 @@ <a href="http://twitter.com/share" class="twitter-share-button" data-url="{{ site.url }}{{ page.url }}" data-via="{{ site.twitter_user }}" data-counturl="{{ site.url }}{{ page.url }}" >Tweet</a> {% endif %} {% if site.google_plus_one %} - <g:plusone size="{{ site.google_plus_one_size }}"></g:plusone> + <div class="g-plusone" data-size="{{ site.google_plus_one_size }}"></div> {% endif %} </div> diff --git a/.themes/classic/source/_layouts/default.html b/.themes/classic/source/_layouts/default.html index 57147575..629468d3 100644 --- a/.themes/classic/source/_layouts/default.html +++ b/.themes/classic/source/_layouts/default.html @@ -5,9 +5,12 @@ <nav role=navigation>{% include navigation.html %}</nav> <div id="main"> <div id="content"> - {{ content | expand_urls: root_url | backtick_codeblock | smart_quotes }} + {{ content | expand_urls: root_url }} </div> </div> <footer>{% include footer.html %}</footer> + {% include google_analytics.html %} + {% include google_plus_one.html %} + {% include twitter_sharing.html %} </body> </html> diff --git a/.themes/classic/source/_layouts/page.html b/.themes/classic/source/_layouts/page.html index 08e056ec..dbf209c4 100644 --- a/.themes/classic/source/_layouts/page.html +++ b/.themes/classic/source/_layouts/page.html @@ -7,7 +7,7 @@ layout: default {% if page.title %} <header> <h1 class="entry-title">{{ page.title | titlecase }}</h1> - {% if page.date %}<p class="meta">{% include post/date.html %}</p>{% endif %} + {% if page.date %}<p class="meta">{% include post/date.html %}{{ time }}</p>{% endif %} </header> {% endif %} {{ content }} @@ -15,7 +15,7 @@ layout: default <footer> {% if page.date or page.author %}<p class="meta"> {% if page.author %}{% include post/author.html %}{% endif %} - {% include post/date.html %} + {% include post/date.html %}{% if updated %}{{ updated }}{% else %}{{ time }}{% endif %} {% if page.categories %}{% include post/categories.html %}{% endif %} </p>{% endif %} {% unless page.sharing == false %} diff --git a/.themes/classic/source/_layouts/post.html b/.themes/classic/source/_layouts/post.html index 78557c04..ce8a5dea 100644 --- a/.themes/classic/source/_layouts/post.html +++ b/.themes/classic/source/_layouts/post.html @@ -9,7 +9,7 @@ single: true <footer> <p class="meta"> {% include post/author.html %} - {% include post/date.html %} + {% include post/date.html %}{% if updated %}{{ updated }}{% else %}{{ time }}{% endif %} {% include post/categories.html %} </p> {% unless page.sharing == false %} diff --git a/.themes/classic/source/javascripts/github.js b/.themes/classic/source/javascripts/github.js new file mode 100644 index 00000000..623d493f --- /dev/null +++ b/.themes/classic/source/javascripts/github.js @@ -0,0 +1,43 @@ +github = (function(){ + function render(target, repos){ + var i = 0, fragment = '', t = $(target)[0]; + + for(i = 0; i < repos.length; i++) + fragment += '<li><a href="'+repos[i].url+'">'+repos[i].name+'</a><p>'+repos[i].description+'</p></li>'; + + t.innerHTML = fragment; + } + return { + showRepos: function(options){ + var feed = new jXHR(); + feed.onerror = function (msg,url) { + $(options.target + ' li.loading').addClass('error').text("Error loading feed"); + } + feed.onreadystatechange = function(data){ + if (feed.readyState === 4) { + var repos = []; + var i; + for (i = 0; i < data.repositories.length; i++){ + if (options.skip_forks && data.repositories[i].fork) + continue; + repos.push(data.repositories[i]); + } + repos.sort(function(a, b){ + var a = new Date(a.pushed_at), + b = new Date(b.pushed_at); + + if (a.valueOf() == b.valueOf()) return 0; + return a.valueOf() > b.valueOf() ? -1 : 1; + }); + + if (options.count) + repos.splice(options.count); + + render(options.target, repos) + } + }; + feed.open("GET","http://github.com/api/v2/json/repos/show/"+options.user+"?callback=?"); + feed.send(); + } + }; +})();
\ No newline at end of file diff --git a/.themes/classic/source/javascripts/twitter.js b/.themes/classic/source/javascripts/twitter.js index 1f1b2f91..a4e85557 100644 --- a/.themes/classic/source/javascripts/twitter.js +++ b/.themes/classic/source/javascripts/twitter.js @@ -68,7 +68,7 @@ function prettyDate(time) { var diff = ((current_date_full - date.getTime()) / 1000); var day_diff = Math.floor(diff / 86400); - if (isNaN(day_diff) || day_diff < 0 || day_diff >= 31) return; + if (isNaN(day_diff) || day_diff < 0) return "<span>∞</span>"; return day_diff == 0 && ( diff < 60 && say.just_now || @@ -78,5 +78,5 @@ function prettyDate(time) { diff < 86400 && Math.floor(diff / 3600) + say.hours_ago) || day_diff == 1 && say.yesterday || day_diff < 7 && day_diff + say.days_ago || - day_diff < 31 && Math.ceil(day_diff / 7) + say.weeks_ago; + day_diff > 7 && Math.ceil(day_diff / 7) + say.weeks_ago; } @@ -1,6 +1,6 @@ source "http://rubygems.org" -group :development do +group :development do gem 'rake' gem 'rack' gem 'jekyll' @@ -14,4 +14,4 @@ group :development do gem 'stringex' end -gem 'sinatra', '1.2.6'
\ No newline at end of file +gem 'sinatra', '1.2.6' diff --git a/Gemfile.lock b/Gemfile.lock index e64b2114..74bca9cb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,11 +1,11 @@ GEM remote: http://rubygems.org/ specs: - RedCloth (4.2.7) + RedCloth (4.2.8) albino (1.3.3) posix-spawn (>= 0.3.6) blankslate (2.1.2.4) - chunky_png (1.2.0) + chunky_png (1.2.1) classifier (1.3.3) fast-stemmer (>= 1.0.0) compass (0.11.5) @@ -29,20 +29,24 @@ GEM maruku (0.6.0) syntax (>= 1.0.0) posix-spawn (0.3.6) - pygments.rb (0.1.2) + pygments.rb (0.1.3) rubypython (>= 0.5.1) rack (1.3.2) rake (0.9.2) - rb-fsevent (0.4.1) + rb-fsevent (0.4.3.1) rdiscount (1.6.8) rubypants (0.2.0) rubypython (0.5.1) blankslate (>= 2.1.2.3) ffi (~> 1.0.7) +<<<<<<< HEAD + sass (3.1.7) +======= sass (3.1.5) sinatra (1.2.6) rack (~> 1.1) tilt (>= 1.2.2, < 2.0) +>>>>>>> 423e8ecbda0394d4c77e2ea659768a8f30c35018 stringex (1.3.0) syntax (1.0.0) tilt (1.3.2) @@ -27,6 +27,9 @@ server_port = "4000" # port for preview server eg. localhost:4000 desc "Initial setup for Octopress: copies the default theme into the path of Jekyll's generator. Rake install defaults to rake install[classic] to install a different theme run rake install[some_theme_name]" task :install, :theme do |t, args| + if File.directory?(source_dir) || File.directory?("sass") + abort("rake aborted!") if ask("A theme is already installed, proceeding will overwrite existing files. Are you sure?", ['y', 'n']) == 'n' + end # copy theme into working Jekyll directories theme = args.theme || 'classic' puts "## Copying "+theme+" theme into ./#{source_dir} and ./sass" @@ -44,30 +47,60 @@ end desc "Generate jekyll site" task :generate do + raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir) puts "## Generating Site with Jekyll" system "jekyll" end desc "Watch the site and regenerate when it changes" task :watch do - system "trap 'kill $jekyllPid $compassPid' Exit; jekyll --auto & jekyllPid=$!; compass watch & compassPid=$!; wait" + raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir) + puts "Starting to watch source with Jekyll and Compass." + jekyllPid = spawn("jekyll --auto") + compassPid = spawn("compass watch") + + trap("INT") { + Process.kill(9, jekyllPid) + Process.kill(9, compassPid) + exit 0 + } + + Process.wait end desc "preview the site in a web browser" task :preview do - system "trap 'kill $jekyllPid $compassPid $rackPid' Exit; jekyll --auto & jekyllPid=$!; compass watch & compassPid=$!; rackup --port #{server_port} & rackPid=$!; wait" + raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir) + puts "Starting to watch source with Jekyll and Compass. Starting Rack on port #{server_port}" + jekyllPid = spawn("jekyll --auto") + compassPid = spawn("compass watch") + rackupPid = spawn("rackup --port #{server_port}") + + trap("INT") { + Process.kill(9, jekyllPid) + Process.kill(9, compassPid) + Process.kill(9, rackupPid) + exit 0 + } + + Process.wait end # usage rake new_post[my-new-post] or rake new_post['my new post'] or rake new_post (defaults to "new-post") desc "Begin a new post in #{source_dir}/#{posts_dir}" task :new_post, :title do |t, args| + raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir) require './plugins/titlecase.rb' + mkdir_p "#{source_dir}/#{posts_dir}" args.with_defaults(:title => 'new-post') title = args.title filename = "#{source_dir}/#{posts_dir}/#{Time.now.strftime('%Y-%m-%d')}-#{title.to_url}.#{new_post_ext}" + if File.exist?(filename) + abort("rake aborted!") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n' + end puts "Creating new post: #{filename}" open(filename, 'w') do |post| - system "mkdir -p #{source_dir}/#{posts_dir}"; + system "mkdir -p #{source_dir}/#{posts_dir}/"; post.puts "---" post.puts "layout: post" post.puts "title: \"#{title.gsub(/&/,'&').titlecase}\"" @@ -81,6 +114,7 @@ end # usage rake new_page[my-new-page] or rake new_page[my-new-page.html] or rake new_page (defaults to "new-page.markdown") desc "Create a new page in #{source_dir}/(filename)/index.#{new_page_ext}" task :new_page, :filename do |t, args| + raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir) require './plugins/titlecase.rb' args.with_defaults(:filename => 'new-page') page_dir = source_dir @@ -91,6 +125,9 @@ task :new_page, :filename do |t, args| filename = "#{name}.#{extension}" mkdir_p page_dir file = page_dir + filename + if File.exist?(file) + abort("rake aborted!") if ask("#{file} already exists. Do you want to overwrite?", ['y', 'n']) == 'n' + end puts "Creating new page: #{file}" open(file, 'w') do |page| page.puts "---" @@ -124,7 +161,7 @@ end desc "Clean out caches: _code_cache, _gist_cache, .sass-cache" task :clean do - system "rm -rf _code_cache/** _gist_cache/** .sass-cache/** source/stylesheets/screen.css" + rm_rf ["_code_cache/**", "_gist_cache/**", ".sass-cache/**", "source/stylesheets/screen.css"] end desc "Move sass to sass.old, install sass theme updates, replace sass/custom with sass.old/custom" @@ -132,11 +169,11 @@ task :update_style, :theme do |t, args| theme = args.theme || 'classic' if File.directory?("sass.old") puts "removed existing sass.old directory" - system "rm -r sass.old" + rm_r "sass.old", :secure=>true end - system "mv sass sass.old" + mv "sass", "sass.old" puts "## Moved styles into sass.old/" - system "mkdir -p sass; cp -R #{themes_dir}/"+theme+"/sass/ sass/" + cp_r "#{themes_dir}/"+theme+"/sass/", "sass" cp_r "sass.old/custom/.", "sass/custom" puts "## Updated Sass ##" end @@ -145,16 +182,15 @@ desc "Move source to source.old, install source theme updates, replace source/_i task :update_source, :theme do |t, args| theme = args.theme || 'classic' if File.directory?("#{source_dir}.old") - puts "removed existing #{source_dir}.old directory" - system "rm -r #{source_dir}.old" + puts "## Removed existing #{source_dir}.old directory" + rm_r "#{source_dir}.old", :secure=>true end - system "mv #{source_dir} #{source_dir}.old" - puts "moved #{source_dir} into #{source_dir}.old/" - system "mkdir -p #{source_dir}; cp -R #{themes_dir}/"+theme+"/source/. #{source_dir}" - system "cp -Rn #{source_dir}.old/. #{source_dir}" - system "cp -Rf #{source_dir}.old/_includes/custom/. #{source_dir}/_includes/custom/" - system "mv -f #{source_dir}/index.html #{blog_index_dir}" if blog_index_dir != source_dir - system "cp -f #{source_dir}.old/index.html #{source_dir}" if blog_index_dir != source_dir + cp_r "#{source_dir}/.", "#{source_dir}.old" + puts "## Copied #{source_dir} into #{source_dir}.old/" + cp_r "#{themes_dir}/"+theme+"/source/.", source_dir, :remove_destination=>true + cp_r "#{source_dir}.old/_includes/custom/.", "#{source_dir}/_includes/custom/", :remove_destination=>true + mv "#{source_dir}/index.html", "#{blog_index_dir}", :force=>true if blog_index_dir != source_dir + cp "#{source_dir}.old/index.html", source_dir if blog_index_dir != source_dir puts "## Updated #{source_dir} ##" end @@ -168,12 +204,10 @@ end desc "copy dot files for deployment" task :copydot do - cd "#{source_dir}" do - exclusions = [".", "..", ".DS_Store"] - Dir[".*"].each do |file| - if !File.directory?(file) && !exclusions.include?(file) - cp(file, "../#{public_dir}"); - end + exclusions = [".", "..", ".DS_Store"] + Dir["#{source_dir}/.*"].each do |file| + if !File.directory?(file) && !exclusions.include?(file) + cp(file, "#{public_dir}"); end end end @@ -266,6 +300,20 @@ def ok_failed(condition) end end +def get_stdin(message) + print message + STDIN.gets.chomp +end + +def ask(message, valid_options) + if valid_options + answer = get_stdin("#{message} #{valid_options.to_s.gsub(/"/, '').gsub(/, /,'/')} ") while !valid_options.include?(answer) + else + answer = get_stdin(message) + end + answer +end + desc "list tasks" task :list do puts "Tasks: #{(Rake::Task.tasks - [Rake::Task[:list]]).join(', ')}" diff --git a/_config.yml b/_config.yml index 00dc8aa4..6d472bf6 100644 --- a/_config.yml +++ b/_config.yml @@ -36,7 +36,7 @@ excerpt_link: "Read on →" # "Continue reading" link text at the bottom of # list each of the sidebar modules you want to include, in the order you want them to appear. # To add custom asides, create files in /source/_includes/custom/asides/ and add them to the list like 'custom/asides/custom_aside_name.html' -default_asides: [asides/recent_posts.html, asides/twitter.html, asides/delicious.html, asides/pinboard.html] +default_asides: [asides/recent_posts.html, asides/github.html, asides/twitter.html, asides/delicious.html, asides/pinboard.html] # Each layout uses the default asides, but they can have their own asides instead. Simply uncomment the lines below # and add an array with the asides you want to use. @@ -48,6 +48,12 @@ default_asides: [asides/recent_posts.html, asides/twitter.html, asides/delicious # 3rd Party Settings # # ----------------------- # +# Github repositories +github_user: +github_repo_count: 0 +github_show_profile_link: true +github_skip_forks: true + # Twitter twitter_user: twitter_tweet_count: 4 diff --git a/plugins/backtick_code_block.rb b/plugins/backtick_code_block.rb new file mode 100644 index 00000000..7f5076df --- /dev/null +++ b/plugins/backtick_code_block.rb @@ -0,0 +1,43 @@ +require './plugins/pygments_code' + +module BacktickCodeBlock + include HighlightCode + AllOptions = /([^\s]+)\s+(.+?)(https?:\/\/\S+)\s*(.+)?/i + LangCaption = /([^\s]+)\s*(.+)?/i + def render_code_block(input) + @options = nil + @caption = nil + @lang = nil + @url = nil + @title = nil + input.gsub /^`{3} *([^\n]+)?\n(.+?)\n`{3}/m do + @options = $1 || '' + str = $2 + + if @options =~ AllOptions + @lang = $1 + @caption = "<figcaption><span>#{$2}</span><a href='#{$3}'>#{$4 || 'link'}</a></figcaption>" + elsif @options =~ LangCaption + @lang = $1 + @caption = "<figcaption><span>#{$2}</span></figcaption>" + end + + if str.match(/\A {4}/) + str = str.gsub /^ {4}/, '' + end + if @lang.nil? || @lang == 'plain' + code = tableize_code(str.gsub('<','<').gsub('>','>')) + "<figure role=code>#{@caption}#{code}</figure>" + else + if @lang.include? "-raw" + raw = "``` #{@options.sub('-raw', '')}\n" + raw += str + raw += "\n```\n" + else + code = highlight(str, @lang) + "<figure role=code>#{@caption}#{code}</figure>" + end + end + end + end +end diff --git a/plugins/category_generator.rb b/plugins/category_generator.rb index aa1180e1..d9357bc8 100644 --- a/plugins/category_generator.rb +++ b/plugins/category_generator.rb @@ -1,3 +1,5 @@ +# encoding: utf-8 +# # Jekyll category page generator. # http://recursive-design.com/projects/jekyll-plugins/ # @@ -16,8 +18,8 @@ # - category_dir: The subfolder to build category pages in (default is 'categories'). # - category_title_prefix: The string used before the category name in the page title (default is # 'Category: '). -module Jekyll +module Jekyll # The CategoryIndex class creates a single category page for the specified category. class CategoryIndex < Page @@ -68,7 +70,7 @@ module Jekyll if self.layouts.key? 'category_index' dir = self.config['category_dir'] || 'categories' self.categories.keys.each do |category| - self.write_category_index(File.join(dir, category.gsub(/_|\W/, '-')), category) + self.write_category_index(File.join(dir, category.gsub(/_|\P{Word}/, '-').gsub(/-{2,}/, '-').downcase), category) end # Throw an exception if the layout couldn't be found. @@ -105,7 +107,7 @@ module Jekyll def category_links(categories) dir = @context.registers[:site].config['category_dir'] categories = categories.sort!.map do |item| - "<a class='category' href='/#{dir}/#{item.gsub(/_|\W/, '-')}/'>#{item}</a>" + "<a class='category' href='/#{dir}/#{item.gsub(/_|\P{Word}/, '-').gsub(/-{2,}/, '-').downcase}/'>#{item}</a>" end case categories.length diff --git a/plugins/code_block.rb b/plugins/code_block.rb index 9c971bf5..00b0b438 100644 --- a/plugins/code_block.rb +++ b/plugins/code_block.rb @@ -42,11 +42,13 @@ # </figure> # require './plugins/pygments_code' +require './plugins/raw' module Jekyll class CodeBlock < Liquid::Block include HighlightCode + include TemplateWrapper CaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)\s+(.+)/i CaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)/i Caption = /(\S[\S\s]*)/ @@ -78,14 +80,15 @@ module Jekyll def render(context) output = super code = super.join - source = "<div><figure role=code>" + source = "<figure role=code>" source += @caption if @caption - source = context['pygments_prefix'] + source if context['pygments_prefix'] if @filetype - source += " #{highlight(code, @filetype)}</figure></div>" + source += " #{highlight(code, @filetype)}</figure>" else - source += "#{tableize_code(code.lstrip.rstrip.gsub(/</,'<'))}</figure></div>" + source += "#{tableize_code(code.lstrip.rstrip.gsub(/</,'<'))}</figure>" end + source = safe_wrap(source) + source = context['pygments_prefix'] + source if context['pygments_prefix'] source = source + context['pygments_suffix'] if context['pygments_suffix'] end end diff --git a/plugins/include_code.rb b/plugins/include_code.rb index 70d5f138..80951cb5 100644 --- a/plugins/include_code.rb +++ b/plugins/include_code.rb @@ -21,12 +21,14 @@ # require './plugins/pygments_code' +require './plugins/raw' require 'pathname' module Jekyll class IncludeCodeTag < Liquid::Tag include HighlightCode + include TemplateWrapper def initialize(tag_name, markup, tokens) @title = nil @file = nil @@ -59,8 +61,9 @@ module Jekyll @filetype = file.extname.sub('.','') if @filetype.nil? title = @title ? "#{@title} (#{file.basename})" : file.basename url = "/#{code_dir}/#{@file}" - source = "<div><figure role=code><figcaption><span>#{title}</span> <a href='#{url}'>download</a></figcaption>\n" - source += " #{highlight(code, @filetype)}</figure></div>" + source = "<figure role=code><figcaption><span>#{title}</span> <a href='#{url}'>download</a></figcaption>\n" + source += " #{highlight(code, @filetype)}</figure>" + safe_wrap(source) end end end diff --git a/plugins/octopress_filters.rb b/plugins/octopress_filters.rb index a63c43ab..1a959892 100644 --- a/plugins/octopress_filters.rb +++ b/plugins/octopress_filters.rb @@ -1,8 +1,38 @@ #custom filters for Octopress -require './plugins/pygments_code' +require './plugins/backtick_code_block' +require './plugins/post_filters' +require './plugins/raw' +require 'rubypants' module OctopressFilters - include HighlightCode + include BacktickCodeBlock + include TemplateWrapper + def pre_filter(input) + input = render_code_block(input) + input.gsub /(<figure.+?>.+?<\/figure>)/m do + safe_wrap($1) + end + end + def post_filter(input) + input = unwrap(input) + RubyPants.new(input).to_html + end +end + +module Jekyll + class ContentFilters < PostFilter + include OctopressFilters + def pre_render(post) + post.content = pre_filter(post.content) + end + def post_render(post) + post.content = post_filter(post.content) + end + end +end + + +module OctopressLiquidFilters # Used on the blog index to split posts on the <!--more--> marker def excerpt(input) if input.index(/<!--\s*more\s*-->/i) @@ -26,45 +56,6 @@ module OctopressFilters end end - # for Github style codeblocks eg. - # ``` ruby - # code snippet - # ``` - def backtick_codeblock(input) - code = nil - # Markdown support - input = input.gsub /<p>`{3}\s*(\w+)?<\/p>\s*<pre><code>\s*(.+?)\s*<\/code><\/pre>\s*<p>`{3}<\/p>/m do - lang = $1 - if lang != '' - str = $2.gsub('<','<').gsub('>','>').gsub('&','&') - code = highlight(str, lang) - "<figure role=code>#{code}</figure>" - else - code = tableize_code($2) - "<figure role=code>#{code}</figure>" - end - end - - # Textile warning - input = input.gsub /<p>`{3}\s*(\w+)?<br\s*\/>\n(.+?)`{3}<\/p>/m do - lang = $1 - "<pre><code>Back tick code blocks are not supported for Textile.\nTry HTML or Markdown instead or use the codeblock tag.\n\n{% codeblock #{lang} %}\nYour code snippet\n{% endcodeblock %}</code></pre>" - end - - # Regular HTML support - input.gsub /^`{3}\s*(\w+)?\n(.+?)\n`{3}/m do - lang = $1 - str = $2.gsub(/^\s{4}/, '') - if lang != '' - code = highlight(str, lang) - "<figure role=code>#{code}</figure>" - else - code = tableize_code($2.gsub('<','<').gsub('>','>')) - "<figure role=code>#{code}</figure>" - end - end - end - # Replaces relative urls with full urls def expand_urls(input, url='') url ||= '/' @@ -88,12 +79,6 @@ module OctopressFilters end end - # replaces primes with smartquotes using RubyPants - def smart_quotes(input) - require 'rubypants' - RubyPants.new(input).to_html - end - # Returns a title cased string based on John Gruber's title case http://daringfireball.net/2008/08/title_case_update def titlecase(input) input.titlecase @@ -127,5 +112,5 @@ module OctopressFilters end end end -Liquid::Template.register_filter OctopressFilters +Liquid::Template.register_filter OctopressLiquidFilters diff --git a/plugins/post_filters.rb b/plugins/post_filters.rb new file mode 100644 index 00000000..08626802 --- /dev/null +++ b/plugins/post_filters.rb @@ -0,0 +1,176 @@ +module Jekyll + + # Extended plugin type that allows the plugin + # to be called on varous callback methods. + # + # Examples: + # https://github.com/tedkulp/octopress/blob/master/plugins/post_metaweblog.rb + # https://github.com/tedkulp/octopress/blob/master/plugins/post_twitter.rb + class PostFilter < Plugin + + #Called before post is sent to the converter. Allows + #you to modify the post object before the converter + #does it's thing + def pre_render(post) + end + + #Called after the post is rendered with the converter. + #Use the post object to modify it's contents before the + #post is inserted into the template. + def post_render(post) + end + + #Called after the post is written to the disk. + #Use the post object to read it's contents to do something + #after the post is safely written. + def post_write(post) + end + end + + # Monkey patch for the Jekyll Site class. For the original class, + # see: https://github.com/mojombo/jekyll/blob/master/lib/jekyll/site.rb + class Site + + # Instance variable to store the various post_filter + # plugins that are loaded. + attr_accessor :post_filters + + # Instantiates all of the post_filter plugins. This is basically + # a duplication of the other loaders in Site#setup. + def load_post_filters + self.post_filters = Jekyll::PostFilter.subclasses.select do |c| + !self.safe || c.safe + end.map do |c| + c.new(self.config) + end + end + end + + # Monkey patch for the Jekyll Post class. For the original class, + # see: https://github.com/mojombo/jekyll/blob/master/lib/jekyll/post.rb + class Post + + # Copy the #write method to #old_write, so we can redefine #write + # method. + alias_method :old_write, :write + + # Write the generated post file to the destination directory. It + # then calls any post_write methods that may exist. + # +dest+ is the String path to the destination dir + # + # Returns nothing + def write(dest) + old_write(dest) + post_write if respond_to?(:post_write) + end + end + + # Monkey patch for the Jekyll Page class. For the original class, + # see: https://github.com/mojombo/jekyll/blob/master/lib/jekyll/page.rb + class Page + + # Copy the #write method to #old_write, so we can redefine #write + # method. + alias_method :old_write, :write + + # Write the generated post file to the destination directory. It + # then calls any post_write methods that may exist. + # +dest+ is the String path to the destination dir + # + # Returns nothing + def write(dest) + old_write(dest) + post_write if respond_to?(:post_write) + end + end + + # Monkey patch for the Jekyll Convertible module. For the original class, + # see: https://github.com/mojombo/jekyll/blob/master/lib/jekyll/convertible.rb + module Convertible + + def is_post? + self.class.to_s == 'Jekyll::Post' + end + + def is_page? + self.class.to_s == 'Jekyll::Page' + end + + def is_filterable? + is_post? or is_page? + end + + # Call the #pre_render methods on all of the loaded + # post_filter plugins. + # + # Returns nothing + def pre_render + self.site.load_post_filters unless self.site.post_filters + + if self.site.post_filters and is_filterable? + self.site.post_filters.each do |filter| + filter.pre_render(self) + end + end + end + + # Call the #post_render methods on all of the loaded + # post_filter plugins. + # + # Returns nothing + def post_render + if self.site.post_filters and is_filterable? + self.site.post_filters.each do |filter| + filter.post_render(self) + end + end + end + + # Call the #post_write methods on all of the loaded + # post_filter plugins. + # + # Returns nothing + def post_write + if self.site.post_filters and is_filterable? + self.site.post_filters.each do |filter| + filter.post_write(self) + end + end + end + + # Copy the #transform method to #old_transform, so we can + # redefine #transform method. + alias_method :old_transform, :transform + + # Transform the contents based on the content type. Then calls the + # #post_render method if it exists + # + # Returns nothing. + def transform + old_transform + post_render if respond_to?(:post_render) + end + + # Copy the #do_layout method to #old_do_layout, so we can + # redefine #do_layout method. + alias_method :old_do_layout, :do_layout + + # Calls the pre_render method if it exists and then adds any necessary + # layouts to this convertible document. + # + # payload - The site payload Hash. + # layouts - A Hash of {"name" => "layout"}. + # + # Returns nothing. + def do_layout(payload, layouts) + pre_render if respond_to?(:pre_render) + old_do_layout(payload, layouts) + end + + # Returns the full url of the post, including the + # configured url + def full_url + self.site.config['url'] + self.url + end + end +end diff --git a/plugins/raw.rb b/plugins/raw.rb new file mode 100644 index 00000000..4b002625 --- /dev/null +++ b/plugins/raw.rb @@ -0,0 +1,40 @@ +# Author: Brandon Mathis +# Description: Provides plugins with a method for wrapping and unwrapping input to prevent Markdown and Textile from parsing it. +# Purpose: This is useful for preventing Markdown and Textile from being too aggressive and incorrectly parsing in-line HTML. +module TemplateWrapper + # Wrap input with a <div> + def safe_wrap(input) + "<div class='bogus-wrapper'><notextile>#{input}</notextile></div>" + end + # This must be applied after the + def unwrap(input) + input.gsub /<div class='bogus-wrapper'><notextile>(.+?)<\/notextile><\/div>/m do + $1 + end + end +end + +# Author: phaer, https://github.com/phaer +# Source: https://gist.github.com/1020852 +# Description: Raw tag for jekyll. Keeps liquid from parsing text betweeen {% raw %} and {% endraw %} + +module Jekyll + class RawTag < Liquid::Block + def parse(tokens) + @nodelist ||= [] + @nodelist.clear + + while token = tokens.shift + if token =~ FullToken + if block_delimiter == $1 + end_tag + return + end + end + @nodelist << token if not token.empty? + end + end + end +end + +Liquid::Template.register_tag('raw', Jekyll::RawTag) diff --git a/plugins/render_partial.rb b/plugins/render_partial.rb index 9f665644..b6ebfe8b 100644 --- a/plugins/render_partial.rb +++ b/plugins/render_partial.rb @@ -22,10 +22,12 @@ # require 'pathname' +require './plugins/octopress_filters' module Jekyll class RenderPartialTag < Liquid::Tag + include OctopressFilters def initialize(tag_name, markup, tokens) @file = nil @raw = false @@ -50,6 +52,7 @@ module Jekyll if contents =~ /\A-{3}.+[^\A]-{3}\n(.+)/m contents = $1.lstrip end + contents = pre_filter(contents) if @raw contents else diff --git a/plugins/sitemap_generator.rb b/plugins/sitemap_generator.rb index 8b6cf78c..b63e9423 100644 --- a/plugins/sitemap_generator.rb +++ b/plugins/sitemap_generator.rb @@ -37,6 +37,7 @@ # Modified for Octopress by John W. Long # require 'rexml/document' +require 'fileutils' module Jekyll @@ -122,6 +123,9 @@ module Jekyll sitemap.add_element(urlset) # File I/O: create sitemap.xml file and write out pretty-printed XML + unless File.exists?(site.dest) + FileUtils.mkdir_p(site.dest) + end file = File.new(File.join(site.dest, SITEMAP_FILE_NAME), "w") formatter = REXML::Formatters::Pretty.new(4) formatter.compact = true |