Last active
July 25, 2020 19:40
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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