diff --git a/Makefile b/Makefile index 00fd2c2..ea82688 100644 --- a/Makefile +++ b/Makefile @@ -6,14 +6,14 @@ MIN_JAVASCRIPTS=assets/blog.min.js assets/gitter.min.js assets/jquery-serializeO assets/request.min.js assets/showdown.min.js assets/storage-polyfill.min.js assets/store.min.js \ assets/strftime.min.js assets/tmpl.min.js -POSTS=$(shell echo _blog/*.html) +POSTS=$(shell echo _blog/published/*.html) all: proj blog combine proj: projects.json templates/proj/index.html templates/proj/proj/index.html ./build.js -blog: _blog/posts.json templates/blog/index.html templates/blog/post.html $(POSTS) +blog: _blog/blog.json templates/blog/index.html templates/blog/post.html $(POSTS) @echo ./blog.rb _blog blog @@ -36,10 +36,11 @@ publish: publish_blog publish_proj index.html publish assets publish blog publish proj + scp blog/posts.json bohodev.net:discussd/posts.json clean: rm -rf proj/* rm -rf blog/* rm assets/*.min.js -.PHONY: blog +.PHONY: proj diff --git a/blog.rb b/blog.rb index 3edc8cf..973e786 100755 --- a/blog.rb +++ b/blog.rb @@ -1,69 +1,144 @@ #!/usr/bin/env ruby +require 'time' require 'rubygems' +require 'builder' require 'json' -require 'rdiscount' require 'mustache' +require 'rdiscount' -srcdir = ARGV.shift.to_s -destdir = ARGV.shift.to_s - -unless File.directory?(srcdir) && File.directory?(destdir) - puts 'usage: blog.rb ' - exit 1 +def main + srcdir = ARGV.shift.to_s + destdir = ARGV.shift.to_s + unless File.directory?(srcdir) && File.directory?(destdir) + puts 'usage: blog.rb ' + exit 1 + end + Blag.go! srcdir, destdir end -template = File.read(File.join('templates', 'blog', 'post.html')) +class Blag + def self.go! src, dest + self.new(src, dest).generate! + end -# read posts -posts_file = File.join(srcdir, 'posts.json') -Posts = JSON.parse(File.read(posts_file)) -posts = Posts['published'].map do |filename| - lines = File.readlines(File.join(srcdir, filename)) - post = { :filename => filename } - loop do - line = lines.shift.strip - m = line.match(/(\w+):/) - if m && param = m[1].downcase - post[param.to_sym] = line.sub(Regexp.new('^' + param + ':\s*', 'i'), '').strip - elsif line.match(/^----\s*$/) - lines.shift while lines.first.strip.empty? - break - else - puts "ignoring unknown header: #{line}" + def initialize src, dest + @src = src + @dest = dest + read_blog + end + + def generate! + generate_posts + generate_index + generate_rss + generate_posts_json + end + + def generate_index + template = File.read(File.join('templates', 'blog', 'index.html')) + # generate landing page + index_template = File.read(File.join('templates', 'blog', 'index.html')) + index_html = Mustache.render(index_template, { :posts => posts, + :post => posts.first, + :previous => posts[1], + :filename => posts.first[:filename], + :comments => posts.first[:comments] + }) + File.open(File.join(@dest, 'index.html'), 'w') {|f| f.puts(index_html) } + end + + def generate_posts + template = File.read(File.join('templates', 'blog', 'post.html')) + posts.each_with_index do |post, i| + post[:html] = Mustache.render(template, { :title => post[:title], + :post => post, + :previous => i < posts.length - 1 && posts[i + 1], + :next => i > 0 && posts[i - 1], + :filename => post[:filename], + :comments => post[:comments] + }) + File.open(File.join(@dest, post[:filename]), 'w') {|f| f.puts(post[:html]) } end end - post[:content] = lines.join - post[:body] = RDiscount.new(post[:content]).to_html - # comments on by default - post[:comments] = true if post[:comments].nil? - post + + def generate_posts_json + json = JSON.generate({ :published => posts.map {|p| p[:filename]} }) + File.open(File.join(@dest, 'posts.json'), 'w') { |f| f.puts(json) } + end + + def generate_rss + File.open(File.join(@dest, 'rss'), 'w') { |f| f.puts(rss.to_s) } + end + + def posts + prefix = File.join(@src, 'published') + '/' + @posts ||= Dir[File.join(prefix, '*')].sort.reverse.map do |filename| + lines = File.readlines(filename) + post = { :filename => filename.sub(prefix, '') } + loop do + line = lines.shift.strip + m = line.match(/(\w+):/) + if m && param = m[1].downcase + post[param.to_sym] = line.sub(Regexp.new('^' + param + ':\s*', 'i'), '').strip + elsif line.match(/^----\s*$/) + lines.shift while lines.first.strip.empty? + break + else + puts "ignoring unknown header: #{line}" + end + end + post[:content] = lines.join + post[:body] = RDiscount.new(post[:content]).to_html + post[:rfc822] = Time.parse(post[:date]).rfc822 + post[:url] = @url + '/' + post[:filename] + # comments on by default + post[:comments] = true if post[:comments].nil? + post + end + end + + def rss + xml = Builder::XmlMarkup.new + xml.instruct! :xml, :version => '1.0' + xml.rss :version => '2.0' do + xml.channel do + xml.title @title + xml.description @subtitle + xml.link @url + xml.pubDate @posts.first[:rfc822] + + posts.each do |post| + xml.item do + xml.title post[:title] + xml.description post[:subtitle] + xml.pubDate post[:rfc822] + xml.link post[:url] + xml.guid post[:url] + end + end + end + end + xml + end + + private + + def blog_file + File.join(@src, 'blog.json') + end + + def read_blog + blog = JSON.parse(File.read(blog_file)) + @title = blog['title'] + @subtitle = blog['subtitle'] + @url = blog['url'] + end + + def rss_file + File.join(@dest, 'rss') + end + end -# generate posts -posts.each_with_index do |post, i| - post[:html] = Mustache.render(template, { :title => post[:title], - :post => post, - :previous => i < posts.length - 1 && posts[i + 1], - :next => i > 0 && posts[i - 1], - :filename => post[:filename], - :comments => post[:comments] - }) -end - -# generate landing page -index_template = File.read(File.join('templates', 'blog', 'index.html')) -index_html = Mustache.render(index_template, { :posts => posts, - :post => posts.first, - :previous => posts[1], - :filename => posts.first[:filename], - :comments => posts.first[:comments] - }) - -# write landing page -File.open(File.join(destdir, 'index.html'), 'w') {|f| f.puts(index_html) } - -# write posts -posts.each do |post| - File.open(File.join(destdir, post[:filename]), 'w') {|f| f.puts(post[:html]) } -end +main if $0 == __FILE__ diff --git a/blog.sh b/blog.sh deleted file mode 100755 index 8874f01..0000000 --- a/blog.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -if [[ ! -d _blog ]]; then - git clone git://github.com/samsonjs/blog.git _blog -else - cd _blog - git pull - cd .. -fi - -./blog.rb _blog diff --git a/blog/using-emacs-to-develop-mojo-apps-for-webos.html b/blog/2009-11-21_using-emacs-to-develop-mojo-apps-for-webos.html similarity index 92% rename from blog/using-emacs-to-develop-mojo-apps-for-webos.html rename to blog/2009-11-21_using-emacs-to-develop-mojo-apps-for-webos.html index 719ded1..22d22ac 100644 --- a/blog/using-emacs-to-develop-mojo-apps-for-webos.html +++ b/blog/2009-11-21_using-emacs-to-develop-mojo-apps-for-webos.html @@ -3,6 +3,7 @@ Using Emacs to Develop Mojo Apps for WebOS :: samhuri.net +
@@ -29,7 +30,7 @@ SJS.filename = "using-emacs-to-develop-mojo-apps-for-webos.html"
-

Using Emacs to Develop Mojo Apps for WebOS

+

Using Emacs to Develop Mojo Apps for WebOS

@@ -152,7 +153,7 @@ SJS.filename = "using-emacs-to-develop-mojo-apps-for-webos.html"

(discussion requires JavaScript)

@@ -162,7 +163,7 @@ SJS.filename = "using-emacs-to-develop-mojo-apps-for-webos.html"
- +

diff --git a/blog/working-with-c-style-structs-in-ruby.html b/blog/2010-01-17_working-with-c-style-structs-in-ruby.html similarity index 90% rename from blog/working-with-c-style-structs-in-ruby.html rename to blog/2010-01-17_working-with-c-style-structs-in-ruby.html index b27c472..a55a599 100644 --- a/blog/working-with-c-style-structs-in-ruby.html +++ b/blog/2010-01-17_working-with-c-style-structs-in-ruby.html @@ -3,6 +3,7 @@ Working with C-style structs in Ruby :: samhuri.net +
@@ -29,7 +30,7 @@ SJS.filename = "working-with-c-style-structs-in-ruby.html"
-

Working with C-style structs in Ruby

+

Working with C-style structs in Ruby

This is the beginning of a series on generating Mach-O object files in @@ -144,8 +145,8 @@ of the Mach-O file format

(discussion requires JavaScript)

@@ -155,7 +156,7 @@ of the Mach-O file format

- +

diff --git a/blog/basics-of-the-mach-o-file-format.html b/blog/2010-01-18_basics-of-the-mach-o-file-format.html similarity index 93% rename from blog/basics-of-the-mach-o-file-format.html rename to blog/2010-01-18_basics-of-the-mach-o-file-format.html index 94ab5f9..ea1f88f 100644 --- a/blog/basics-of-the-mach-o-file-format.html +++ b/blog/2010-01-18_basics-of-the-mach-o-file-format.html @@ -3,6 +3,7 @@ Basics of the Mach-O file format :: samhuri.net +
@@ -29,7 +30,7 @@ SJS.filename = "basics-of-the-mach-o-file-format.html"
-

Basics of the Mach-O file format

+

Basics of the Mach-O file format

This post is part of a series on generating basic x86 Mach-O files @@ -295,8 +296,8 @@ would almost have a useful Mach object file.)

(discussion requires JavaScript)

@@ -306,7 +307,7 @@ would almost have a useful Mach object file.)

- +

diff --git a/blog/a-preview-of-mach-o-file-generation.html b/blog/2010-01-20_a-preview-of-mach-o-file-generation.html similarity index 84% rename from blog/a-preview-of-mach-o-file-generation.html rename to blog/2010-01-20_a-preview-of-mach-o-file-generation.html index 03b5dff..cb9766f 100644 --- a/blog/a-preview-of-mach-o-file-generation.html +++ b/blog/2010-01-20_a-preview-of-mach-o-file-generation.html @@ -3,6 +3,7 @@ A preview of Mach-O file generation :: samhuri.net +
@@ -29,7 +30,7 @@ SJS.filename = "a-preview-of-mach-o-file-generation.html"
-

A preview of Mach-O file generation

+

A preview of Mach-O file generation

This month I got back into an x86 compiler I started last May. It lives

(discussion requires JavaScript)

@@ -83,7 +84,7 @@ straightforward, an example is in asm/binary.rb, in the #output method.

- +

diff --git a/blog/37signals-chalk-dissected.html b/blog/2010-11-04_37signals-chalk-dissected.html similarity index 97% rename from blog/37signals-chalk-dissected.html rename to blog/2010-11-04_37signals-chalk-dissected.html index 79e0961..3fa18ba 100644 --- a/blog/37signals-chalk-dissected.html +++ b/blog/2010-11-04_37signals-chalk-dissected.html @@ -3,6 +3,7 @@ 37signals' Chalk Dissected :: samhuri.net +
@@ -29,7 +30,7 @@ SJS.filename = "37signals-chalk-dissected.html"
-

37signals' Chalk Dissected

+

37signals' Chalk Dissected

Update 2010-11-05: I dove into the JavaScript a little and explained most of it. Sam Stephenson tweeted that Chalk is written in CoffeeScript and compiled on the fly when served using Brochure. That's hot! (for those unaware Sam Stephenson works at 37signals, and is also the man behind Prototype.)

@@ -278,7 +279,7 @@ addLineNumbersToAllGists();

(discussion requires JavaScript)

@@ -288,7 +289,7 @@ addLineNumbersToAllGists();
- +

diff --git a/blog/index.html b/blog/index.html index 8a83e9e..e55366d 100644 --- a/blog/index.html +++ b/blog/index.html @@ -1,8 +1,9 @@ -blog :: samhuri.net +sjs' blog +
@@ -38,18 +39,18 @@ SJS.filename = "37signals-chalk-dissected.html"

(discussion requires JavaScript)

@@ -308,7 +309,7 @@ addLineNumbersToAllGists();
- +

diff --git a/blog/posts.json b/blog/posts.json new file mode 100644 index 0000000..fed0d48 --- /dev/null +++ b/blog/posts.json @@ -0,0 +1 @@ +{"published":["2010-11-04_37signals-chalk-dissected.html","2010-01-20_a-preview-of-mach-o-file-generation.html","2010-01-18_basics-of-the-mach-o-file-format.html","2010-01-17_working-with-c-style-structs-in-ruby.html","2009-11-21_using-emacs-to-develop-mojo-apps-for-webos.html"]} diff --git a/blog/rss b/blog/rss new file mode 100644 index 0000000..9434282 --- /dev/null +++ b/blog/rss @@ -0,0 +1 @@ +sjs' blogramblings and musingshttp://samhuri.net/blogThu, 04 Nov 2010 00:00:00 -070037signals' Chalk DissectedThu, 04 Nov 2010 00:00:00 -0700http://samhuri.net/blog/2010-11-04_37signals-chalk-dissected.htmlhttp://samhuri.net/blog/2010-11-04_37signals-chalk-dissected.htmlA preview of Mach-O file generationWed, 20 Jan 2010 00:00:00 -0800http://samhuri.net/blog/2010-01-20_a-preview-of-mach-o-file-generation.htmlhttp://samhuri.net/blog/2010-01-20_a-preview-of-mach-o-file-generation.htmlBasics of the Mach-O file formatMon, 18 Jan 2010 00:00:00 -0800http://samhuri.net/blog/2010-01-18_basics-of-the-mach-o-file-format.htmlhttp://samhuri.net/blog/2010-01-18_basics-of-the-mach-o-file-format.htmlWorking with C-style structs in RubySun, 17 Jan 2010 00:00:00 -0800http://samhuri.net/blog/2010-01-17_working-with-c-style-structs-in-ruby.htmlhttp://samhuri.net/blog/2010-01-17_working-with-c-style-structs-in-ruby.htmlUsing Emacs to Develop Mojo Apps for WebOSSat, 21 Nov 2009 00:00:00 -0800http://samhuri.net/blog/2009-11-21_using-emacs-to-develop-mojo-apps-for-webos.htmlhttp://samhuri.net/blog/2009-11-21_using-emacs-to-develop-mojo-apps-for-webos.html diff --git a/templates/blog/index.html b/templates/blog/index.html index e027779..1cd1663 100644 --- a/templates/blog/index.html +++ b/templates/blog/index.html @@ -1,8 +1,9 @@ -blog :: samhuri.net +sjs' blog +