Skip to content

Instantly share code, notes, and snippets.

@code-later
Created April 10, 2012 12:28
Show Gist options
  • Save code-later/2351046 to your computer and use it in GitHub Desktop.
Save code-later/2351046 to your computer and use it in GitHub Desktop.
Convert a MovableType export to single Markdown posts to use with Octopress
#!/usr/bin/env ruby
require 'date'
require 'mustache'
require 'stringex'
require 'cgi'
export = File.open(ARGV[0])
target_dir = ARGV[1]
class Post < Mustache
self.template = <<-MARKDOWN
---
layout: post
title: "{{title}}"
date: {{formatted_date}}
comments: {{comments}}
categories: {{category}}
author: {{author}}
---
{{formatted_body}}
MARKDOWN
attr_accessor :author, :title, :category, :comments, :status, :body
def initialize
@body = []
end
def date=(date)
case date
when String
@date = DateTime.strptime(date, "%m/%d/%Y %I:%M:%S %p")
else
@date = date
end
end
def date
@date
end
def formatted_date
@date.strftime("%Y-%m-%d %H:%M")
end
def comments=(comments)
@comments = comments == "1" ? true : false
end
def formatted_body
CGI.unescapeHTML(body.join).
gsub(/<a href="(.*?)">*(.*?)<\/a>/i, '[\2](\1)').
gsub("<!--more-->", "\n\n<!-- more -->\n\n")
end
def file_name
"#{date.strftime("%Y-%m-%d")}-#{title.to_url}.markdown"
end
end
posts = [Post.new]
KEYWORDS = /(AUTHOR|TITLE|STATUS|COMMENTS|CATEGORY|DATE): (.*)/
def attr_and_value(line)
line =~ KEYWORDS
["#{$1.downcase}=", $2]
end
puts " # Reading from data '#{ARGV[0]}' ..."
puts " # Generating Markdown ..."
comment_section = false
export.each do |line|
if line.strip == "--------"
posts << Post.new
print '.'
comment_section = false
next
end
next if comment_section
case line.strip
when KEYWORDS
posts.last.send(*attr_and_value(line))
when /BODY/
next
when "-----"
next
when /COMMENT:/
comment_section = true
next
else
posts.last.body << line
end
end
puts
puts " # Writing files to #{target_dir} ..."
`mkdir -p #{target_dir}`
`cd #{target_dir} && rm -rf _posts && mkdir _posts`
ok, fails = 0, 0
posts.each do |post|
begin
File.open(File.join(target_dir, "_posts", post.file_name), "w+") { |f| f.puts post.render }
puts " -> #{post.file_name}"
ok += 1
rescue
puts " # Could not write file for '#{post.title}'"
fails += 1
end
end
puts
puts " # All done! (#{ok}/#{fails})"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment