Skip to content

Instantly share code, notes, and snippets.

@arika
Last active December 31, 2015 10:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arika/7974269 to your computer and use it in GitHub Desktop.
Save arika/7974269 to your computer and use it in GitHub Desktop.
three rake tasks for jekyll - scaffold new post, open last edited post, and open latest post.
class PostEditor
FILENAME_MSG = '(you can leave this blank)'
POST_TEMPLATE = <<-Template
---
title:
_filename_: #{FILENAME_MSG}
categories:
-
tags:
-
date: #{Time.now.strftime('%Y-%m-%d %H:%M')}
layout: post
comments: true
---
Template
include Jekyll::Convertible
def initialize
assert_editor
end
attr_accessor :data, :content
def create_post(ext = '.markdown')
FileUtils.mkdir_p('_posts', verbose: true)
Tempfile.open(['jekyll_new_post_', ext]) do |tf|
tf.print POST_TEMPLATE
tf.close
execute_editor(tf.path)
save_new_post(tf)
end
end
def edit_last_post
newest_post = Dir.glob('_posts/*').
select {|x| File.file?(x) && /\A\./ !~ x }.
sort_by {|x| File.mtime(x) }.last
execute_editor(newest_post)
end
def edit_latest_post
latest_post = Dir.glob('_posts/*').
select {|x| File.file?(x) && /\A\./ !~ x }.
sort_by {|x| File.basename(x) }.last
execute_editor(latest_post)
end
def site
nil
end
def converter
nil
end
private
def assert_editor
raise 'set EDITOR!' unless ENV['EDITOR']
end
def execute_editor(path)
raise 'no file to edit' unless path
system ENV['EDITOR'], path
raise "#{ENV['EDITOR']} failed" unless $?.success?
end
def save_new_post(tmpfile)
read_yaml(*File.split(tmpfile.path))
%w(tags categories).each do |key|
data[key].compact!
end
time = data['date']
unless time.is_a?(Time)
time = Time.parse(time) rescue Time.now
end
filename = (data.delete('_filename_') || '').strip
if filename == FILENAME_MSG.strip || filename.empty?
filename = (data['title'] || '').strip
end
filename_base = File.join(
'_posts',
time.strftime('%Y-%m-%d-') +
filename.gsub(/[\s\W]/, '-'))
ext = File.extname(tmpfile.path)
num = 1
begin
path = filename_base +
(num == 1 ? '' : "-#{num}") + ext
File.open(path, File::RDWR|File::CREAT|File::EXCL) do |io|
io.print YAML.dump(data)
io.puts '---'
io.puts self.content.chomp
end
return path
rescue Errno::EEXIST
num += 1
if num == 10
raise "new post can not be saved correctly\ncheck filename or title of your new post"
end
retry
end
rescue Exception
msg = "your content saved in "
begin
expath =
tmpfile.path[0, tmpfile.path.size - ext.size] +
Time.now.strftime('_%Y%m%d_%H%M%S') + ext
FileUtils.mv(tmpfile.path, expath)
msg << expath
rescue Exception
ObjectSpace.undefine_finalizer(tmpfile) # XXX: これで大丈夫?
msg << tmpfile.path
end
raise $!.class, "#{$!.message}\n#{msg}", $!.backtrace
end
end
require 'rubygems'
require 'fileutils'
require 'open-uri'
require 'pathname'
task :bundler do
require 'bundler/setup'
Bundler.require(:default)
require 'jekyll'
require './_libs/post_editor'
end
desc 'Write a new post'
task :new => [:bundler] do
path = PostEditor.new.create_post
Rake.rake_output_message "content saved in #{path}\n'rake last' can open the file"
end
desc 'Open the last edited post'
task :last => [:bundler] do
PostEditor.new.edit_last_post
end
desc 'Open the newest post'
task :latest => [:bundler] do
PostEditor.new.edit_latest_post
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment