#!/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 #{counter}
\"\"
#{counter} Description
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