Skip to content

Instantly share code, notes, and snippets.

@garrettdimon
Last active July 25, 2020 19:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save garrettdimon/74fece1e19206817aeac104609cfad1d to your computer and use it in GitHub Desktop.
Save garrettdimon/74fece1e19206817aeac104609cfad1d to your computer and use it in GitHub Desktop.
A Ruby script to facilitate starting to write a new Jekyll post and automatically do all the things related to preparing that.
#!/usr/bin/env ruby
require 'optparse'
require 'ostruct'
require 'pp'
class Article
attr_accessor :options, :file
def initialize(arguments)
@options = parse arguments
@file = File.open(filename, "a")
end
def save
add_frontmatter if file_blank?
add_image_markup if images?
file.close
reload_jekyll
do_work
end
private
def title
options[:title]
end
def description
options[:description]
end
def images?
options[:images]
end
def draft?
options[:draft]
end
def any_images_to_add?
entries = Dir.entries(images_dir)
exclusions = %w{ . .. OpenGraph.png }
(entries - exclusions).any?
end
def file_blank?
File.zero?(filename)
end
def add_frontmatter
file.puts(frontmatter)
end
def add_image_markup
setup_source_image_directory
setup_article_image_directory
puts "\n\nIt puts the images in the directory, and hits enter when ready..."
puts "\n(Don't forget 'OpenGraph.png')\n\n"
`say 'Add your images'`
gets
file.puts(image_markup) if any_images_to_add?
end
def setup_source_image_directory
if Dir.exists?(images_source_dir)
system("open #{images_source_dir}")
end
end
def setup_article_image_directory
unless Dir.exists?(images_dir)
Dir.mkdir(images_dir)
end
system("open #{images_dir}")
end
def image_markup
image_markup = ["\n\n## Image Pull Options\n\n* pull\n* pull-full\n* pull-left\n* pull-right\n* pull-clean\n* pull-seprate\n\n"]
counter = 0
Dir.foreach(images_dir) do |item|
skippable = ['.', '..', '.DS_Store', 'OpenGraph.png']
next if skippable.include?(item)
counter += 1
image_markup << image_markup_for(item, counter)
end
if image_markup.size > 1
return image_markup.join("\n\n")
else
return ''
end
end
def do_work
# Open Safari & Text Editor
system("open -a safari #{local_web_address}")
system("subl #{filename}")
end
def reload_jekyll
# Jekyll isn't good at recognizing new files, so let's ditch any
# existing instances and start fresh
# Unless Jekyll is already running, let's start it up
jekyll_instances = (`ps aux | grep [j]ekyll`).split(/\n/)
jekyll_instances.each do |instance|
instance =~ /\w+\s+(\d+)\s.+/i
pid = $1
`kill -9 #{pid}`
end
system("jekyll serve --watch --detach")
# Wait a moment for everything to propogate
sleep 5 # seconds
end
def frontmatter
str = <<-eot
---
title: #{title}
date: #{date_slug} 00:00:00 -06:00
author: Garrett Dimon
author_handle: garrettdimon
description: #{description}
layout: post
image: #{opengraph_image}
#{draft? ? 'state: draft' : ''}
---
eot
end
def image_markup_for(image, counter)
str = <<-eot
<span class=\"ref\">#{counter}</span>
<figure class=\"pull\">
<img src=\"/images/#{slug}/#{image}\" alt=\"\" />
<figcaption>
<b>#{counter}</b>
Description
</figcaption>
</figure>
eot
end
# ex. "/Users/garrettdimon/Sites/garrettdimon.com/blog/images/2015-06-22-article-name-like-this"
def images_dir
"#{directory}/images/#{slug}"
end
def opengraph_image
# https://garrettdimon.com/blog/images/2015-06-14-milestone-overview-calendar/MilestonesCalendar.png
"https://garrettdimon.com/images/#{slug}/OpenGraph.png"
end
# ex. "./blog/_posts/2015-06-22-article-name-like-this.markdown"
def filename
section_folder = draft? ? "drafts" : "posts"
"./_#{section_folder}/#{slug}.markdown"
end
# ex. "2015-06-22-article-name-like-this"
def slug
"#{date_slug}-#{title_slug}"
end
# ex. "article-name-like-this"
def title_slug
# Strip _'s, replace spaces with '-', and ditch non-alphanumerics
@ts ||= title.
downcase.
gsub('_', '').
gsub(' ', '-').
gsub(/[^a-z0-9-]/, '')
end
# ex. "2015-06-22"
def date_slug
@ds ||= Time.now.strftime '%Y-%m-%d'
end
# ex. "2015/06/"
def archive_folder_slug
@as ||= Time.now.strftime '%Y/'
end
# ex. "/2015/article-name-like-this"
def archive_path
@ap ||= "#{archive_folder_slug}#{title_slug}/"
end
# This is the working directory for compiling images that will be used in the
# post. If it's present, it will automatically be opened in Finder for easy
# drag and drop into the new post directory.
def images_source_dir
"/Users/garrettdimon/Desktop/NewArticleImages/"
end
# For know what URL to open in the browser for previewing the new post.
def local_web_address
"http://127.0.0.1:4000/"
end
def directory
Dir.pwd
end
def parse(options)
args = OpenStruct.new
args.title = ""
args.description = "#TODO"
args.images = false
args.draft = false
opt_parser = OptionParser.new do |opts|
opts.banner = "Usage: write.rb [options]"
opts.on("-t", "--title=TITLE", "Title of the article") do |t|
args.title = t
end
opts.on("-d", "--desc=DESCRIPTION", "Meta description for article") do |s|
args.description = d
end
opts.on("-f", "--draft", "If the article should be a draft for now") do |f|
args.draft = true
end
opts.on("-i", "--images", "If the article includes images") do |i|
args.images = true
end
opts.on("-h", "--help", "Prints this help") do
puts opts
exit
end
end
opt_parser.parse!(options)
return args
end
end
article = Article.new(ARGV).save
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment