From 913fa105c4a6793e6522ca45b85d8f06c803c6b9 Mon Sep 17 00:00:00 2001 From: Brandon Mathis Date: Sat, 11 Jun 2011 15:58:53 -0400 Subject: 1. Moved _plugins into themes/classic/_plugins I think it's probably better to ship plugins with themes to make it easier to update them. 2. Improved 'install' rake task and made nicer output --- Rakefile | 10 +- _plugins/blockquote.rb | 109 --------- _plugins/category.rb | 65 ----- _plugins/compass_compiler.rb | 1 - _plugins/custom_filters.rb | 59 ----- _plugins/generate_sitemap.rb | 133 ---------- _plugins/gist_tag.rb | 83 ------- _plugins/haml.rb | 24 -- _plugins/iterator.rb | 49 ---- _plugins/pygments_cache_patch.rb | 30 --- _plugins/titlecase.rb | 36 --- themes/classic/_plugins/blockquote.rb | 109 +++++++++ themes/classic/_plugins/category.rb | 65 +++++ themes/classic/_plugins/compass_compiler.rb | 1 + themes/classic/_plugins/custom_filters.rb | 59 +++++ themes/classic/_plugins/generate_sitemap.rb | 133 ++++++++++ themes/classic/_plugins/gist_tag.rb | 83 +++++++ themes/classic/_plugins/haml.rb | 24 ++ themes/classic/_plugins/iterator.rb | 49 ++++ themes/classic/_plugins/pygments_cache_patch.rb | 30 +++ themes/classic/_plugins/sitemap_generator.rb | 309 ++++++++++++++++++++++++ themes/classic/_plugins/titlecase.rb | 36 +++ 22 files changed, 905 insertions(+), 592 deletions(-) delete mode 100644 _plugins/blockquote.rb delete mode 100644 _plugins/category.rb delete mode 100644 _plugins/compass_compiler.rb delete mode 100644 _plugins/custom_filters.rb delete mode 100644 _plugins/generate_sitemap.rb delete mode 100644 _plugins/gist_tag.rb delete mode 100644 _plugins/haml.rb delete mode 100644 _plugins/iterator.rb delete mode 100644 _plugins/pygments_cache_patch.rb delete mode 100644 _plugins/titlecase.rb create mode 100644 themes/classic/_plugins/blockquote.rb create mode 100644 themes/classic/_plugins/category.rb create mode 100644 themes/classic/_plugins/compass_compiler.rb create mode 100644 themes/classic/_plugins/custom_filters.rb create mode 100644 themes/classic/_plugins/generate_sitemap.rb create mode 100644 themes/classic/_plugins/gist_tag.rb create mode 100644 themes/classic/_plugins/haml.rb create mode 100644 themes/classic/_plugins/iterator.rb create mode 100644 themes/classic/_plugins/pygments_cache_patch.rb create mode 100644 themes/classic/_plugins/sitemap_generator.rb create mode 100644 themes/classic/_plugins/titlecase.rb diff --git a/Rakefile b/Rakefile index 33e115c3..7158ebb1 100644 --- a/Rakefile +++ b/Rakefile @@ -25,9 +25,13 @@ task :install, :theme do |t, args| # copy theme into working Jekyll directories theme = args.theme || 'classic' puts "## Copying "+theme+" theme to Jekyll paths" - system "cp -R themes/"+theme+"/source source" - system "cp -R themes/"+theme+"/sass sass" - # system "cp -R themes/"+theme+"/_plugins/ _plugins/" + system "mkdir -p #{source}; cp -R themes/"+theme+"/source/ #{source}/" + system "mkdir -p sass; cp -R themes/"+theme+"/sass/ sass/" + system "mkdir -p _plugins; cp -R themes/"+theme+"/_plugins/ _plugins/" + system "mkdir -p #{source}/_posts"; + puts "## Layouts, images, and javascritps from the #{theme} theme have been installed into ./#{source}" + puts "## Sass stylesheet sources from the #{theme} theme have been installed into ./sass" + puts "## Plugins from the #{theme} theme have been installed into ./_plugins" end ####################### diff --git a/_plugins/blockquote.rb b/_plugins/blockquote.rb deleted file mode 100644 index 7a885175..00000000 --- a/_plugins/blockquote.rb +++ /dev/null @@ -1,109 +0,0 @@ -# -# Author: Josediaz Gonzalez - https://github.com/josegonzalez -# Source URL: https://github.com/josegonzalez/josediazgonzalez.com/blob/master/_plugins/blockquote.rb -# Modified by Brandon Mathis -# -require './_plugins/titlecase.rb' -module Jekyll - - # Outputs a string with a given attribution as a quote - # - # {% blockquote John Paul Jones %} - # Monkeys! - # {% endblockquote %} - # ... - #
- # Monkeys! - #
- # John Paul Jones - #
- # - class Blockquote < Liquid::Block - FullCiteWithTitle = /([\w\s]+)(https?:\/\/)(\S+\s)([\w\s]+)/i - FullCite = /([\w\s]+)(https?:\/\/)(\S+)/i - Author = /([\w\s]+)/ - - def initialize(tag_name, markup, tokens) - @by = nil - @source = nil - @title = nil - if markup =~ FullCiteWithTitle - @by = $1 - @source = $2 + $3 - @title = $4.titlecase - elsif markup =~ FullCite - @by = $1 - @source = $2 + $3 - elsif markup =~ Author - @by = $1 - end - super - end - - def render(context) - output = super - if @by.nil? - '

' + output.join + '

' - elsif !@title.nil? - '

' + output.join + '

' + '

' + @by + '' + '' + @title + '

' - elsif !@source.nil? - '

' + output.join + '

' + '

' + @by + '' + 'source

' - else - '

' + output.join + '

' + '

' + @by + '

' - end - end - end - - # Outputs a string with a given attribution as a pullquote - # - # {% blockquote John Paul Jones %} - # Monkeys! - # {% endblockquote %} - # ... - #
- # Monkeys! - #
- # John Paul Jones - #
- # - class Pullquote < Liquid::Block - FullCiteWithTitle = /([\w\s]+)(http:\/\/|https:\/\/)(\S+)([\w\s]+)/i - FullCite = /([\w\s]+)(http:\/\/|https:\/\/)(\S+)/i - Author = /([\w\s]+)/ - - def initialize(tag_name, markup, tokens) - @by = nil - @source = nil - @title = nil - if markup =~ FullCiteWithTitle - @by = $1 - @source = $2 + $3 - @title = $4 - elsif markup =~ FullCite - @by = $1 - @source = $2 + $3 - elsif markup =~ Author - @by = $1 - end - super - end - - def render(context) - output = super - if @by.nil? - '

' + output.join + '

' - elsif @title - '

' + output.join + '

' + '

' + @by + '' + ' ' + @title + '

' - elsif @source - '

' + output.join + '

' + '

' + @by + '' + ' source

' - elsif @by - '

' + output.join + '

' + '

' + @by + '

' - end - end - end -end - -Liquid::Template.register_tag('blockquote', Jekyll::Blockquote) -Liquid::Template.register_tag('pullquote', Jekyll::Pullquote) - - diff --git a/_plugins/category.rb b/_plugins/category.rb deleted file mode 100644 index b9accdec..00000000 --- a/_plugins/category.rb +++ /dev/null @@ -1,65 +0,0 @@ -module Jekyll - - class CategoryIndex < Page - def initialize(site, base, dir, category) - @site = site - @base = base - @dir = dir - @name = 'index.html' - - self.process(@name) - self.read_yaml(File.join(base, '_layouts'), 'category_index.html') - self.data['category'] = category - - category_title_prefix = site.config['category_title_prefix'] || 'Category: ' - self.data['title'] = "#{category_title_prefix}#{category}" - end - end - - class CategoryList < Page - def initialize(site, base, dir, categories) - @site = site - @base = base - @dir = dir - @name = 'index.html' - - self.process(@name) - self.read_yaml(File.join(base, '_layouts'), 'category_list.html') - self.data['categories'] = categories - end - end - - class CategoryGenerator < Generator - safe true - - def generate(site) - if site.layouts.key? 'category_index' - dir = site.config['category_dir'] || 'categories' - site.categories.keys.each do |category| - write_category_index(site, File.join(dir, category.gsub(/\s/, "-").gsub(/[^\w-]/, '').downcase), category) - end - end - - if site.layouts.key? 'category_list' - dir = site.config['category_dir'] || 'categories' - write_category_list(site, dir, site.categories.keys.sort) - end - end - - def write_category_index(site, dir, category) - index = CategoryIndex.new(site, site.source, dir, category) - index.render(site.layouts, site.site_payload) - index.write(site.dest) - site.static_files << index - end - - def write_category_list(site, dir, categories) - index = CategoryList.new(site, site.source, dir, categories) - index.render(site.layouts, site.site_payload) - index.write(site.dest) - site.static_files << index - end - end - -end - diff --git a/_plugins/compass_compiler.rb b/_plugins/compass_compiler.rb deleted file mode 100644 index dcec746a..00000000 --- a/_plugins/compass_compiler.rb +++ /dev/null @@ -1 +0,0 @@ -system "compass compile --css-dir source/stylesheets" diff --git a/_plugins/custom_filters.rb b/_plugins/custom_filters.rb deleted file mode 100644 index 158586af..00000000 --- a/_plugins/custom_filters.rb +++ /dev/null @@ -1,59 +0,0 @@ -#custom filters for Octopress - -module OctopressFilters - def exerpt(input, url, url_text="Reade more…", permalink_text=false) - if input.index(//i) - input.split(//i)[0] + "

#{url_text}

" - elsif permalink_text - input + "

#{permalink_text}

" - else - input - end - end - def full_urls(input, url='') - input.gsub /(\s+(href|src)\s*=\s*["|']{1})(\/[^\"'>]+)/ do - $1+url+$3 - end - end - def search_url(input) - input.gsub /(http:\/\/)(\S+)/ do - $2 - end - end - def smart_quotes(input) - require 'rubypants' - RubyPants.new(input).to_html - end - def titlecase(input) - input.titlecase - end - def datetime(date) - if date.class == String - date = Time.parse(date) - end - date - end - def ordinalize(date) - date = datetime(date) - "#{date.strftime('%B')} #{ordinal(date.strftime('%e').to_i)}, #{date.strftime('%Y')}" - end - def ordinal(number) - if (11..13).include?(number.to_i % 100) - "#{number}th" - else - case number.to_i % 10 - when 1; "#{number}st" - when 2; "#{number}nd" - when 3; "#{number}rd" - else "#{number}th" - end - end - end - #YearlyPost = Struct.new('YearlyPost', :year, :posts) - def yearly_posts(site) - #site.posts.reverse.group_by { |p| p.date.strftime("%Y") }.map { |k,v| YearlyPost.new(k,v) } - site - end -end -Liquid::Template.register_filter OctopressFilters - diff --git a/_plugins/generate_sitemap.rb b/_plugins/generate_sitemap.rb deleted file mode 100644 index 4d580c47..00000000 --- a/_plugins/generate_sitemap.rb +++ /dev/null @@ -1,133 +0,0 @@ -# Jekyll sitemap page generator. -# http://recursive-design.com/projects/jekyll-plugins/ -# -# Version: 0.1.3 (201101061053) -# -# Copyright (c) 2010 Dave Perrett, http://recursive-design.com/ -# Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) -# -# A generator that creates a sitemap.xml page for jekyll sites, suitable for submission to -# google etc. -# -# To use it, simply drop this script into the _plugins directory of your Jekyll site. -# -# When you compile your jekyll site, this plugin will loop through the list of pages in your -# site, and generate an entry in sitemap.xml for each one. - -require 'pathname' - -module Jekyll - - - # Monkey-patch an accessor for a page's containing folder, since - # we need it to generate the sitemap. - class Page - def subfolder - @dir - end - end - - - # Sub-class Jekyll::StaticFile to allow recovery from unimportant exception - # when writing the sitemap file. - class StaticSitemapFile < StaticFile - def write(dest) - super(dest) rescue ArgumentError - true - end - end - - - # Generates a sitemap.xml file containing URLs of all pages and posts. - class SitemapGenerator < Generator - safe true - priority :low - - # Domain that you are generating the sitemap for - update this to match your site. - - # Generates the sitemap.xml file. - # - # +site+ is the global Site object. - def generate(site) - # Create the destination folder if necessary. - site_folder = site.config['destination'] - unless File.directory?(site_folder) - p = Pathname.new(site_folder) - p.mkdir - end - - # Write the contents of sitemap.xml. - File.open(File.join(site_folder, 'sitemap.xml'), 'w') do |f| - f.write(generate_header()) - f.write(generate_content(site)) - f.write(generate_footer()) - f.close - end - - # Add a static file entry for the zip file, otherwise Site::cleanup will remove it. - site.static_files << Jekyll::StaticSitemapFile.new(site, site.dest, '/', 'sitemap.xml') - end - - private - - # Returns the XML header. - def generate_header - "\n" - end - - # Returns a string containing the the XML entries. - # - # +site+ is the global Site object. - def generate_content(site) - result = '' - - base_url = site.config['url'] - - # First, try to find any stand-alone pages. - site.pages.each{ |page| - path = page.subfolder + '/' + page.name - mod_date = File.mtime(site.source + path) - - # Remove the trailing 'index.html' if there is one, and just output the folder name. - if path=~/index.html$/ - path = path[0..-11] - end - - unless path =~/error/ - result += entry(base_url, path, mod_date) - end - } - - # Next, find all the posts. - posts = site.site_payload['site']['posts'] - for post in posts do - result += entry(base_url, post.id, post.date) - end - - result - end - - # Returns the XML footer. - def generate_footer - "\n" - end - - # Creates an XML entry from the given path and date. - # - # +path+ is the URL path to the page. - # +date+ is the date the file was modified (in the case of regular pages), or published (for blog posts). - def entry(base_url, path, date) - # Force extensions to .html from markdown, textile. - path = path.gsub(/\.(markdown|textile)$/i, '.html') - " - - #{base_url}#{path} - #{date.strftime("%Y-%m-%d")} - " - end - - end - -end - - diff --git a/_plugins/gist_tag.rb b/_plugins/gist_tag.rb deleted file mode 100644 index 1f37416e..00000000 --- a/_plugins/gist_tag.rb +++ /dev/null @@ -1,83 +0,0 @@ -# Nicked from Brandon Tilly -# Gist https://gist.github.com/803483 -# Post http://brandontilley.com/2011/01/31/gist-tag-for-jekyll.html -# -# Example usage: {% gist 803483 gist_tag.rb %} //embeds a gist for this plugin - -require 'digest/md5' -require 'net/https' -require 'uri' - -module Jekyll - class GistTag < Liquid::Tag - def initialize(tag_name, text, token) - super - system('mkdir -p .gist_cache') - @text = text - @cache = true - @cache_folder = File.expand_path "../.gist_cache", File.dirname(__FILE__) - end - - def render(context) - return "" unless @text =~ /([\d]*) (.*)/ - - gist, file = $1.strip, $2.strip - script_url = "https://gist.github.com/#{gist}.js?file=#{file}" - - code = get_cached_gist(gist, file) || get_gist_from_web(gist, file) - code = code.gsub "<", "<" - string = "" - string += "" - return string - end - - def get_gist_url_for(gist, file) - "https://gist.github.com/raw/#{gist}/#{file}" - end - - def cache_gist(gist, file, data) - file = get_cache_file_for gist, file - File.open(file, "w+") do |f| - f.write(data) - end - end - - def get_cached_gist(gist, file) - return nil if @cache == false - file = get_cache_file_for gist, file - return nil unless File.exist?(file) - return File.new(file).readlines.join - end - - def get_cache_file_for(gist, file) - gist.gsub! /[^a-zA-Z0-9\-_\.]/, '' - file.gsub! /[^a-zA-Z0-9\-_\.]/, '' - md5 = Digest::MD5.hexdigest "#{gist}-#{file}" - File.join @cache_folder, "#{gist}-#{file}-#{md5}.cache" - end - - def get_gist_from_web(gist, file) - gist_url = get_gist_url_for(gist, file) - raw_uri = URI.parse(gist_url) - https = Net::HTTP.new(raw_uri.host, raw_uri.port) - https.use_ssl = true - https.verify_mode = OpenSSL::SSL::VERIFY_NONE - request = Net::HTTP::Get.new(raw_uri.request_uri) - data = https.request(request) - data = data.body - cache_gist(gist, file, data) unless @cache == false - data - end - end - - class GistTagNoCache < GistTag - def initialize(tag_name, text, token) - super - @cache = false - end - end -end - -Liquid::Template.register_tag('gist', Jekyll::GistTag) -Liquid::Template.register_tag('gistnocache', Jekyll::GistTagNoCache) - diff --git a/_plugins/haml.rb b/_plugins/haml.rb deleted file mode 100644 index 7e548dec..00000000 --- a/_plugins/haml.rb +++ /dev/null @@ -1,24 +0,0 @@ -module Jekyll - require 'haml' - class HamlConverter < Converter - safe true - priority :low - - def matches(ext) - ext =~ /haml/i - end - - def output_ext(ext) - ".html" - end - - def convert(content) - begin - engine = Haml::Engine.new(content) - engine.render - rescue StandardError => e - puts "!!! HAML Error: " + e.message - end - end - end -end diff --git a/_plugins/iterator.rb b/_plugins/iterator.rb deleted file mode 100644 index da0b5f0a..00000000 --- a/_plugins/iterator.rb +++ /dev/null @@ -1,49 +0,0 @@ -## -## Author: Jose Gonzalez - https://github.com/josegonzalez -## Source URL: https://github.com/josegonzalez/josediazgonzalez.com/blob/master/_plugins/iterator.rb -## - -#module Jekyll - #class Site - #alias_method :orig_site_payload, :site_payload - - ## Constuct an array of hashes that will allow the user, using Liquid, to - ## iterate through the keys of _kv_hash_ and be able to iterate through the - ## elements under each key. - ## - ## Example: - ## categories = { 'Ruby' => [, ] } - ## make_iterable(categories, :index => 'name', :items => 'posts') - ## Will allow the user to iterate through all categories and then iterate - ## though each post in the current category like so: - ## {% for category in site.categories %} - ## h1. {{ category.name }} - ##
    - ## {% for post in category.posts %} - ##
  • {{ post.title }}
  • - ## {% endfor %} - ##
- ## {% endfor %} - ## - ## Returns [ { => , => kv_hash[]}, ... ] - - #def make_iterable(kv_hash, options) - #options = {:index => 'name', :items => 'items'}.merge(options) - #result = [] - #kv_hash.sort.each do |key, value| - #result << { options[:index] => key, options[:items] => value } - #end - #result - #end - - #def site_payload - #payload = orig_site_payload - #payload['site']['iterable'].merge!({ - #'categories' => make_iterable(self.categories, :index => 'name', :items => 'posts'), - #'tags' => make_iterable(self.tags, :index => 'name', :items => 'posts') - #}) - #payload - #end - - #end -#end diff --git a/_plugins/pygments_cache_patch.rb b/_plugins/pygments_cache_patch.rb deleted file mode 100644 index 36c78d20..00000000 --- a/_plugins/pygments_cache_patch.rb +++ /dev/null @@ -1,30 +0,0 @@ -# -# Author: Raimonds Simanovskis, http://blog.rayapps.com/ -# Source URL: https://github.com/rsim/blog.rayapps.com/blob/master/_plugins/pygments_cache_patch.rb -# - -require 'fileutils' -require 'digest/md5' - -PYGMENTS_CACHE_DIR = File.expand_path('../../_cache', __FILE__) -FileUtils.mkdir_p(PYGMENTS_CACHE_DIR) - -Jekyll::HighlightBlock.class_eval do - def render_pygments(context, code) - if defined?(PYGMENTS_CACHE_DIR) - path = File.join(PYGMENTS_CACHE_DIR, "#{@lang}-#{Digest::MD5.hexdigest(code)}.html") - if File.exist?(path) - highlighted_code = File.read(path) - else - highlighted_code = Albino.new(code, @lang).to_s(@options) - File.open(path, 'w') {|f| f.print(highlighted_code) } - end - else - highlighted_code = Albino.new(code, @lang).to_s(@options) - end - output = add_code_tags(highlighted_code, @lang) - output = context["pygments_prefix"] + output if context["pygments_prefix"] - output = output + context["pygments_suffix"] if context["pygments_suffix"] - output - end -end diff --git a/_plugins/titlecase.rb b/_plugins/titlecase.rb deleted file mode 100644 index 103bf702..00000000 --- a/_plugins/titlecase.rb +++ /dev/null @@ -1,36 +0,0 @@ -class String - def titlecase - small_words = %w(a an and as at but by en for if in of on or the to v v. via vs vs.) - - x = split(" ").map do |word| - # note: word could contain non-word characters! - # downcase all small_words, capitalize the rest - small_words.include?(word.gsub(/\W/, "").downcase) ? word.downcase! : word.smart_capitalize! - word - end - # capitalize first and last words - x.first.to_s.smart_capitalize! - x.last.to_s.smart_capitalize! - # small words after colons are capitalized - x.join(" ").gsub(/:\s?(\W*#{small_words.join("|")}\W*)\s/) { ": #{$1.smart_capitalize} " } - end - - def titlecase! - replace(titlecase) - end - - def smart_capitalize - # ignore any leading crazy characters and capitalize the first real character - if self =~ /^['"\(\[']*([a-z])/ - i = index($1) - x = self[i,self.length] - # word with capitals and periods mid-word are left alone - self[i,1] = self[i,1].upcase unless x =~ /[A-Z]/ or x =~ /\.\w+/ - end - self - end - - def smart_capitalize! - replace(smart_capitalize) - end -end diff --git a/themes/classic/_plugins/blockquote.rb b/themes/classic/_plugins/blockquote.rb new file mode 100644 index 00000000..7a885175 --- /dev/null +++ b/themes/classic/_plugins/blockquote.rb @@ -0,0 +1,109 @@ +# +# Author: Josediaz Gonzalez - https://github.com/josegonzalez +# Source URL: https://github.com/josegonzalez/josediazgonzalez.com/blob/master/_plugins/blockquote.rb +# Modified by Brandon Mathis +# +require './_plugins/titlecase.rb' +module Jekyll + + # Outputs a string with a given attribution as a quote + # + # {% blockquote John Paul Jones %} + # Monkeys! + # {% endblockquote %} + # ... + #
+ # Monkeys! + #
+ # John Paul Jones + #
+ # + class Blockquote < Liquid::Block + FullCiteWithTitle = /([\w\s]+)(https?:\/\/)(\S+\s)([\w\s]+)/i + FullCite = /([\w\s]+)(https?:\/\/)(\S+)/i + Author = /([\w\s]+)/ + + def initialize(tag_name, markup, tokens) + @by = nil + @source = nil + @title = nil + if markup =~ FullCiteWithTitle + @by = $1 + @source = $2 + $3 + @title = $4.titlecase + elsif markup =~ FullCite + @by = $1 + @source = $2 + $3 + elsif markup =~ Author + @by = $1 + end + super + end + + def render(context) + output = super + if @by.nil? + '

' + output.join + '

' + elsif !@title.nil? + '

' + output.join + '

' + '

' + @by + '' + '' + @title + '

' + elsif !@source.nil? + '

' + output.join + '

' + '

' + @by + '' + 'source

' + else + '

' + output.join + '

' + '

' + @by + '

' + end + end + end + + # Outputs a string with a given attribution as a pullquote + # + # {% blockquote John Paul Jones %} + # Monkeys! + # {% endblockquote %} + # ... + #
+ # Monkeys! + #
+ # John Paul Jones + #
+ # + class Pullquote < Liquid::Block + FullCiteWithTitle = /([\w\s]+)(http:\/\/|https:\/\/)(\S+)([\w\s]+)/i + FullCite = /([\w\s]+)(http:\/\/|https:\/\/)(\S+)/i + Author = /([\w\s]+)/ + + def initialize(tag_name, markup, tokens) + @by = nil + @source = nil + @title = nil + if markup =~ FullCiteWithTitle + @by = $1 + @source = $2 + $3 + @title = $4 + elsif markup =~ FullCite + @by = $1 + @source = $2 + $3 + elsif markup =~ Author + @by = $1 + end + super + end + + def render(context) + output = super + if @by.nil? + '

' + output.join + '

' + elsif @title + '

' + output.join + '

' + '

' + @by + '' + ' ' + @title + '

' + elsif @source + '

' + output.join + '

' + '

' + @by + '' + ' source

' + elsif @by + '

' + output.join + '

' + '

' + @by + '

' + end + end + end +end + +Liquid::Template.register_tag('blockquote', Jekyll::Blockquote) +Liquid::Template.register_tag('pullquote', Jekyll::Pullquote) + + diff --git a/themes/classic/_plugins/category.rb b/themes/classic/_plugins/category.rb new file mode 100644 index 00000000..b9accdec --- /dev/null +++ b/themes/classic/_plugins/category.rb @@ -0,0 +1,65 @@ +module Jekyll + + class CategoryIndex < Page + def initialize(site, base, dir, category) + @site = site + @base = base + @dir = dir + @name = 'index.html' + + self.process(@name) + self.read_yaml(File.join(base, '_layouts'), 'category_index.html') + self.data['category'] = category + + category_title_prefix = site.config['category_title_prefix'] || 'Category: ' + self.data['title'] = "#{category_title_prefix}#{category}" + end + end + + class CategoryList < Page + def initialize(site, base, dir, categories) + @site = site + @base = base + @dir = dir + @name = 'index.html' + + self.process(@name) + self.read_yaml(File.join(base, '_layouts'), 'category_list.html') + self.data['categories'] = categories + end + end + + class CategoryGenerator < Generator + safe true + + def generate(site) + if site.layouts.key? 'category_index' + dir = site.config['category_dir'] || 'categories' + site.categories.keys.each do |category| + write_category_index(site, File.join(dir, category.gsub(/\s/, "-").gsub(/[^\w-]/, '').downcase), category) + end + end + + if site.layouts.key? 'category_list' + dir = site.config['category_dir'] || 'categories' + write_category_list(site, dir, site.categories.keys.sort) + end + end + + def write_category_index(site, dir, category) + index = CategoryIndex.new(site, site.source, dir, category) + index.render(site.layouts, site.site_payload) + index.write(site.dest) + site.static_files << index + end + + def write_category_list(site, dir, categories) + index = CategoryList.new(site, site.source, dir, categories) + index.render(site.layouts, site.site_payload) + index.write(site.dest) + site.static_files << index + end + end + +end + diff --git a/themes/classic/_plugins/compass_compiler.rb b/themes/classic/_plugins/compass_compiler.rb new file mode 100644 index 00000000..dcec746a --- /dev/null +++ b/themes/classic/_plugins/compass_compiler.rb @@ -0,0 +1 @@ +system "compass compile --css-dir source/stylesheets" diff --git a/themes/classic/_plugins/custom_filters.rb b/themes/classic/_plugins/custom_filters.rb new file mode 100644 index 00000000..158586af --- /dev/null +++ b/themes/classic/_plugins/custom_filters.rb @@ -0,0 +1,59 @@ +#custom filters for Octopress + +module OctopressFilters + def exerpt(input, url, url_text="Reade more…", permalink_text=false) + if input.index(//i) + input.split(//i)[0] + "

#{url_text}

" + elsif permalink_text + input + "

#{permalink_text}

" + else + input + end + end + def full_urls(input, url='') + input.gsub /(\s+(href|src)\s*=\s*["|']{1})(\/[^\"'>]+)/ do + $1+url+$3 + end + end + def search_url(input) + input.gsub /(http:\/\/)(\S+)/ do + $2 + end + end + def smart_quotes(input) + require 'rubypants' + RubyPants.new(input).to_html + end + def titlecase(input) + input.titlecase + end + def datetime(date) + if date.class == String + date = Time.parse(date) + end + date + end + def ordinalize(date) + date = datetime(date) + "#{date.strftime('%B')} #{ordinal(date.strftime('%e').to_i)}, #{date.strftime('%Y')}" + end + def ordinal(number) + if (11..13).include?(number.to_i % 100) + "#{number}th" + else + case number.to_i % 10 + when 1; "#{number}st" + when 2; "#{number}nd" + when 3; "#{number}rd" + else "#{number}th" + end + end + end + #YearlyPost = Struct.new('YearlyPost', :year, :posts) + def yearly_posts(site) + #site.posts.reverse.group_by { |p| p.date.strftime("%Y") }.map { |k,v| YearlyPost.new(k,v) } + site + end +end +Liquid::Template.register_filter OctopressFilters + diff --git a/themes/classic/_plugins/generate_sitemap.rb b/themes/classic/_plugins/generate_sitemap.rb new file mode 100644 index 00000000..4d580c47 --- /dev/null +++ b/themes/classic/_plugins/generate_sitemap.rb @@ -0,0 +1,133 @@ +# Jekyll sitemap page generator. +# http://recursive-design.com/projects/jekyll-plugins/ +# +# Version: 0.1.3 (201101061053) +# +# Copyright (c) 2010 Dave Perrett, http://recursive-design.com/ +# Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) +# +# A generator that creates a sitemap.xml page for jekyll sites, suitable for submission to +# google etc. +# +# To use it, simply drop this script into the _plugins directory of your Jekyll site. +# +# When you compile your jekyll site, this plugin will loop through the list of pages in your +# site, and generate an entry in sitemap.xml for each one. + +require 'pathname' + +module Jekyll + + + # Monkey-patch an accessor for a page's containing folder, since + # we need it to generate the sitemap. + class Page + def subfolder + @dir + end + end + + + # Sub-class Jekyll::StaticFile to allow recovery from unimportant exception + # when writing the sitemap file. + class StaticSitemapFile < StaticFile + def write(dest) + super(dest) rescue ArgumentError + true + end + end + + + # Generates a sitemap.xml file containing URLs of all pages and posts. + class SitemapGenerator < Generator + safe true + priority :low + + # Domain that you are generating the sitemap for - update this to match your site. + + # Generates the sitemap.xml file. + # + # +site+ is the global Site object. + def generate(site) + # Create the destination folder if necessary. + site_folder = site.config['destination'] + unless File.directory?(site_folder) + p = Pathname.new(site_folder) + p.mkdir + end + + # Write the contents of sitemap.xml. + File.open(File.join(site_folder, 'sitemap.xml'), 'w') do |f| + f.write(generate_header()) + f.write(generate_content(site)) + f.write(generate_footer()) + f.close + end + + # Add a static file entry for the zip file, otherwise Site::cleanup will remove it. + site.static_files << Jekyll::StaticSitemapFile.new(site, site.dest, '/', 'sitemap.xml') + end + + private + + # Returns the XML header. + def generate_header + "\n" + end + + # Returns a string containing the the XML entries. + # + # +site+ is the global Site object. + def generate_content(site) + result = '' + + base_url = site.config['url'] + + # First, try to find any stand-alone pages. + site.pages.each{ |page| + path = page.subfolder + '/' + page.name + mod_date = File.mtime(site.source + path) + + # Remove the trailing 'index.html' if there is one, and just output the folder name. + if path=~/index.html$/ + path = path[0..-11] + end + + unless path =~/error/ + result += entry(base_url, path, mod_date) + end + } + + # Next, find all the posts. + posts = site.site_payload['site']['posts'] + for post in posts do + result += entry(base_url, post.id, post.date) + end + + result + end + + # Returns the XML footer. + def generate_footer + "\n" + end + + # Creates an XML entry from the given path and date. + # + # +path+ is the URL path to the page. + # +date+ is the date the file was modified (in the case of regular pages), or published (for blog posts). + def entry(base_url, path, date) + # Force extensions to .html from markdown, textile. + path = path.gsub(/\.(markdown|textile)$/i, '.html') + " + + #{base_url}#{path} + #{date.strftime("%Y-%m-%d")} + " + end + + end + +end + + diff --git a/themes/classic/_plugins/gist_tag.rb b/themes/classic/_plugins/gist_tag.rb new file mode 100644 index 00000000..1f37416e --- /dev/null +++ b/themes/classic/_plugins/gist_tag.rb @@ -0,0 +1,83 @@ +# Nicked from Brandon Tilly +# Gist https://gist.github.com/803483 +# Post http://brandontilley.com/2011/01/31/gist-tag-for-jekyll.html +# +# Example usage: {% gist 803483 gist_tag.rb %} //embeds a gist for this plugin + +require 'digest/md5' +require 'net/https' +require 'uri' + +module Jekyll + class GistTag < Liquid::Tag + def initialize(tag_name, text, token) + super + system('mkdir -p .gist_cache') + @text = text + @cache = true + @cache_folder = File.expand_path "../.gist_cache", File.dirname(__FILE__) + end + + def render(context) + return "" unless @text =~ /([\d]*) (.*)/ + + gist, file = $1.strip, $2.strip + script_url = "https://gist.github.com/#{gist}.js?file=#{file}" + + code = get_cached_gist(gist, file) || get_gist_from_web(gist, file) + code = code.gsub "<", "<" + string = "" + string += "" + return string + end + + def get_gist_url_for(gist, file) + "https://gist.github.com/raw/#{gist}/#{file}" + end + + def cache_gist(gist, file, data) + file = get_cache_file_for gist, file + File.open(file, "w+") do |f| + f.write(data) + end + end + + def get_cached_gist(gist, file) + return nil if @cache == false + file = get_cache_file_for gist, file + return nil unless File.exist?(file) + return File.new(file).readlines.join + end + + def get_cache_file_for(gist, file) + gist.gsub! /[^a-zA-Z0-9\-_\.]/, '' + file.gsub! /[^a-zA-Z0-9\-_\.]/, '' + md5 = Digest::MD5.hexdigest "#{gist}-#{file}" + File.join @cache_folder, "#{gist}-#{file}-#{md5}.cache" + end + + def get_gist_from_web(gist, file) + gist_url = get_gist_url_for(gist, file) + raw_uri = URI.parse(gist_url) + https = Net::HTTP.new(raw_uri.host, raw_uri.port) + https.use_ssl = true + https.verify_mode = OpenSSL::SSL::VERIFY_NONE + request = Net::HTTP::Get.new(raw_uri.request_uri) + data = https.request(request) + data = data.body + cache_gist(gist, file, data) unless @cache == false + data + end + end + + class GistTagNoCache < GistTag + def initialize(tag_name, text, token) + super + @cache = false + end + end +end + +Liquid::Template.register_tag('gist', Jekyll::GistTag) +Liquid::Template.register_tag('gistnocache', Jekyll::GistTagNoCache) + diff --git a/themes/classic/_plugins/haml.rb b/themes/classic/_plugins/haml.rb new file mode 100644 index 00000000..7e548dec --- /dev/null +++ b/themes/classic/_plugins/haml.rb @@ -0,0 +1,24 @@ +module Jekyll + require 'haml' + class HamlConverter < Converter + safe true + priority :low + + def matches(ext) + ext =~ /haml/i + end + + def output_ext(ext) + ".html" + end + + def convert(content) + begin + engine = Haml::Engine.new(content) + engine.render + rescue StandardError => e + puts "!!! HAML Error: " + e.message + end + end + end +end diff --git a/themes/classic/_plugins/iterator.rb b/themes/classic/_plugins/iterator.rb new file mode 100644 index 00000000..da0b5f0a --- /dev/null +++ b/themes/classic/_plugins/iterator.rb @@ -0,0 +1,49 @@ +## +## Author: Jose Gonzalez - https://github.com/josegonzalez +## Source URL: https://github.com/josegonzalez/josediazgonzalez.com/blob/master/_plugins/iterator.rb +## + +#module Jekyll + #class Site + #alias_method :orig_site_payload, :site_payload + + ## Constuct an array of hashes that will allow the user, using Liquid, to + ## iterate through the keys of _kv_hash_ and be able to iterate through the + ## elements under each key. + ## + ## Example: + ## categories = { 'Ruby' => [, ] } + ## make_iterable(categories, :index => 'name', :items => 'posts') + ## Will allow the user to iterate through all categories and then iterate + ## though each post in the current category like so: + ## {% for category in site.categories %} + ## h1. {{ category.name }} + ##
    + ## {% for post in category.posts %} + ##
  • {{ post.title }}
  • + ## {% endfor %} + ##
+ ## {% endfor %} + ## + ## Returns [ { => , => kv_hash[]}, ... ] + + #def make_iterable(kv_hash, options) + #options = {:index => 'name', :items => 'items'}.merge(options) + #result = [] + #kv_hash.sort.each do |key, value| + #result << { options[:index] => key, options[:items] => value } + #end + #result + #end + + #def site_payload + #payload = orig_site_payload + #payload['site']['iterable'].merge!({ + #'categories' => make_iterable(self.categories, :index => 'name', :items => 'posts'), + #'tags' => make_iterable(self.tags, :index => 'name', :items => 'posts') + #}) + #payload + #end + + #end +#end diff --git a/themes/classic/_plugins/pygments_cache_patch.rb b/themes/classic/_plugins/pygments_cache_patch.rb new file mode 100644 index 00000000..36c78d20 --- /dev/null +++ b/themes/classic/_plugins/pygments_cache_patch.rb @@ -0,0 +1,30 @@ +# +# Author: Raimonds Simanovskis, http://blog.rayapps.com/ +# Source URL: https://github.com/rsim/blog.rayapps.com/blob/master/_plugins/pygments_cache_patch.rb +# + +require 'fileutils' +require 'digest/md5' + +PYGMENTS_CACHE_DIR = File.expand_path('../../_cache', __FILE__) +FileUtils.mkdir_p(PYGMENTS_CACHE_DIR) + +Jekyll::HighlightBlock.class_eval do + def render_pygments(context, code) + if defined?(PYGMENTS_CACHE_DIR) + path = File.join(PYGMENTS_CACHE_DIR, "#{@lang}-#{Digest::MD5.hexdigest(code)}.html") + if File.exist?(path) + highlighted_code = File.read(path) + else + highlighted_code = Albino.new(code, @lang).to_s(@options) + File.open(path, 'w') {|f| f.print(highlighted_code) } + end + else + highlighted_code = Albino.new(code, @lang).to_s(@options) + end + output = add_code_tags(highlighted_code, @lang) + output = context["pygments_prefix"] + output if context["pygments_prefix"] + output = output + context["pygments_suffix"] if context["pygments_suffix"] + output + end +end diff --git a/themes/classic/_plugins/sitemap_generator.rb b/themes/classic/_plugins/sitemap_generator.rb new file mode 100644 index 00000000..3d5530b7 --- /dev/null +++ b/themes/classic/_plugins/sitemap_generator.rb @@ -0,0 +1,309 @@ +# Sitemap.xml Generator is a Jekyll plugin that generates a sitemap.xml file by +# traversing all of the available posts and pages. +# +# How To Use: +# 1.) Copy source file into your _plugins folder within your Jekyll project. +# 2.) Change MY_URL to reflect your domain name. +# 3.) Change SITEMAP_FILE_NAME if you want your sitemap to be called something +# other than sitemap.xml. +# 4.) Change the PAGES_INCLUDE_POSTS list to include any pages that are looping +# through your posts (e.g. "index.html", "archive.html", etc.). This will +# ensure that right after you make a new post, the last modified date will +# be updated to reflect the new post. +# 5.) Run Jekyll: jekyll --server to re-generate your site. +# 6.) A sitemap.xml should be included in your _site folder. +# +# Customizations: +# 1.) If there are any files you don't want included in the sitemap, add them +# to the EXCLUDED_FILES list. The name should match the name of the source +# file. +# 2.) If you want to include the optional changefreq and priority attributes, +# simply include custom variables in the YAML Front Matter of that file. +# The names of these custom variables are defined below in the +# CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME and PRIORITY_CUSTOM_VARIABLE_NAME +# constants. +# +# Notes: +# 1.) The last modified date is determined by the latest from the following: +# system modified date of the page or post, system modified date of +# included layout, system modified date of included layout within that +# layout, ... +# +# Author: Michael Levin +# Site: http://www.kinnetica.com +# Distributed Under A Creative Commons License +# - http://creativecommons.org/licenses/by/3.0/ + +require 'rexml/document' + +module Jekyll + + # Change MY_URL to reflect the site you are using + MY_URL = "http://www.mysite.com" + + # Change SITEMAP_FILE_NAME if you would like your sitemap file + # to be called something else + SITEMAP_FILE_NAME = "sitemap.xml" + + # Any files to exclude from being included in the sitemap.xml + EXCLUDED_FILES = ["atom.xml"] + + # Any files that include posts, so that when a new post is added, the last + # modified date of these pages should take that into account + PAGES_INCLUDE_POSTS = ["index.html"] + + # Custom variable names for changefreq and priority elements + # These names are used within the YAML Front Matter of pages or posts + # for which you want to include these properties + CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME = "change_frequency" + PRIORITY_CUSTOM_VARIABLE_NAME = "priority" + + class Post + attr_accessor :name + + def full_path_to_source + File.join(@base, @name) + end + + def location_on_server + "#{MY_URL}#{url}" + end + end + + class Page + attr_accessor :name + + def full_path_to_source + File.join(@base, @dir, @name) + end + + def location_on_server + location = "#{MY_URL}#{@dir}#{url}" + location.gsub(/index.html$/, "") + end + end + + class Layout + def full_path_to_source + File.join(@base, @name) + end + end + + # Recover from strange exception when starting server without --auto + class SitemapFile < StaticFile + def write(dest) + begin + super(dest) + rescue + end + + true + end + end + + class SitemapGenerator < Generator + + # Valid values allowed by sitemap.xml spec for change frequencies + VALID_CHANGE_FREQUENCY_VALUES = ["always", "hourly", "daily", "weekly", + "monthly", "yearly", "never"] + + # Goes through pages and posts and generates sitemap.xml file + # + # Returns nothing + def generate(site) + sitemap = REXML::Document.new << REXML::XMLDecl.new("1.0", "UTF-8") + + urlset = REXML::Element.new "urlset" + urlset.add_attribute("xmlns", + "http://www.sitemaps.org/schemas/sitemap/0.9") + + @last_modified_post_date = fill_posts(site, urlset) + fill_pages(site, urlset) + + sitemap.add_element(urlset) + + # File I/O: create sitemap.xml file and write out pretty-printed XML + file = File.new(File.join(site.dest, SITEMAP_FILE_NAME), "w") + formatter = REXML::Formatters::Pretty.new(4) + formatter.compact = true + formatter.write(sitemap, file) + file.close + + # Keep the sitemap.xml file from being cleaned by Jekyll + site.static_files << Jekyll::SitemapFile.new(site, site.dest, "/", SITEMAP_FILE_NAME) + end + + # Create url elements for all the posts and find the date of the latest one + # + # Returns last_modified_date of latest post + def fill_posts(site, urlset) + last_modified_date = nil + site.posts.each do |post| + if !excluded?(post.name) + url = fill_url(site, post) + urlset.add_element(url) + end + + path = post.full_path_to_source + date = File.mtime(path) + last_modified_date = date if last_modified_date == nil or date > last_modified_date + end + + last_modified_date + end + + # Create url elements for all the normal pages and find the date of the + # index to use with the pagination pages + # + # Returns last_modified_date of index page + def fill_pages(site, urlset) + site.pages.each do |page| + if !excluded?(page.name) + path = page.full_path_to_source + if File.exists?(path) + url = fill_url(site, page) + urlset.add_element(url) + end + end + end + end + + # Fill data of each URL element: location, last modified, + # change frequency (optional), and priority. + # + # Returns url REXML::Element + def fill_url(site, page_or_post) + url = REXML::Element.new "url" + + loc = fill_location(page_or_post) + url.add_element(loc) + + lastmod = fill_last_modified(site, page_or_post) + url.add_element(lastmod) if lastmod + + if (page_or_post.data[CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME]) + change_frequency = + page_or_post.data[CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME].downcase + + if (valid_change_frequency?(change_frequency)) + changefreq = REXML::Element.new "changefreq" + changefreq.text = change_frequency + url.add_element(changefreq) + else + puts "ERROR: Invalid Change Frequency In #{page_or_post.name}" + end + end + + if (page_or_post.data[PRIORITY_CUSTOM_VARIABLE_NAME]) + priority_value = page_or_post.data[PRIORITY_CUSTOM_VARIABLE_NAME] + if valid_priority?(priority_value) + priority = REXML::Element.new "priority" + priority.text = page_or_post.data[PRIORITY_CUSTOM_VARIABLE_NAME] + url.add_element(priority) + else + puts "ERROR: Invalid Priority In #{page_or_post.name}" + end + end + + url + end + + # Get URL location of page or post + # + # Returns the location of the page or post + def fill_location(page_or_post) + loc = REXML::Element.new "loc" + loc.text = page_or_post.location_on_server + + loc + end + + # Fill lastmod XML element with the last modified date for the page or post. + # + # Returns lastmod REXML::Element or nil + def fill_last_modified(site, page_or_post) + path = page_or_post.full_path_to_source + + lastmod = REXML::Element.new "lastmod" + date = File.mtime(path) + latest_date = find_latest_date(date, site, page_or_post) + + if @last_modified_post_date == nil + # This is a post + lastmod.text = latest_date.iso8601 + else + # This is a page + if posts_included?(page_or_post.name) + # We want to take into account the last post date + final_date = greater_date(latest_date, @last_modified_post_date) + lastmod.text = final_date.iso8601 + else + lastmod.text = latest_date.iso8601 + end + end + lastmod + end + + # Go through the page/post and any implemented layouts and get the latest + # modified date + # + # Returns formatted output of latest date of page/post and any used layouts + def find_latest_date(latest_date, site, page_or_post) + layouts = site.layouts + layout = layouts[page_or_post.data["layout"]] + while layout + path = layout.full_path_to_source + date = File.mtime(path) + + latest_date = date if (date > latest_date) + + layout = layouts[layout.data["layout"]] + end + + latest_date + end + + # Which of the two dates is later + # + # Returns latest of two dates + def greater_date(date1, date2) + if (date1 >= date2) + date1 + else + date2 + end + end + + # Is the page or post listed as something we want to exclude? + # + # Returns boolean + def excluded?(name) + EXCLUDED_FILES.include? name + end + + def posts_included?(name) + PAGES_INCLUDE_POSTS.include? name + end + + # Is the change frequency value provided valid according to the spec + # + # Returns boolean + def valid_change_frequency?(change_frequency) + VALID_CHANGE_FREQUENCY_VALUES.include? change_frequency + end + + # Is the priority value provided valid according to the spec + # + # Returns boolean + def valid_priority?(priority) + begin + priority_val = Float(priority) + return true if priority_val >= 0.0 and priority_val <= 1.0 + rescue ArgumentError + end + + false + end + end +end + diff --git a/themes/classic/_plugins/titlecase.rb b/themes/classic/_plugins/titlecase.rb new file mode 100644 index 00000000..103bf702 --- /dev/null +++ b/themes/classic/_plugins/titlecase.rb @@ -0,0 +1,36 @@ +class String + def titlecase + small_words = %w(a an and as at but by en for if in of on or the to v v. via vs vs.) + + x = split(" ").map do |word| + # note: word could contain non-word characters! + # downcase all small_words, capitalize the rest + small_words.include?(word.gsub(/\W/, "").downcase) ? word.downcase! : word.smart_capitalize! + word + end + # capitalize first and last words + x.first.to_s.smart_capitalize! + x.last.to_s.smart_capitalize! + # small words after colons are capitalized + x.join(" ").gsub(/:\s?(\W*#{small_words.join("|")}\W*)\s/) { ": #{$1.smart_capitalize} " } + end + + def titlecase! + replace(titlecase) + end + + def smart_capitalize + # ignore any leading crazy characters and capitalize the first real character + if self =~ /^['"\(\[']*([a-z])/ + i = index($1) + x = self[i,self.length] + # word with capitals and periods mid-word are left alone + self[i,1] = self[i,1].upcase unless x =~ /[A-Z]/ or x =~ /\.\w+/ + end + self + end + + def smart_capitalize! + replace(smart_capitalize) + end +end -- cgit v1.2.1