Skip to content

Instantly share code, notes, and snippets.

@bbohling
Forked from code-later/README.markdown
Last active January 4, 2016 21:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bbohling/8679316 to your computer and use it in GitHub Desktop.
Save bbohling/8679316 to your computer and use it in GitHub Desktop.

UPDATES:

  • Will process files with either .markdown or .md file extension
  • Set language to en_US

This is a very rough script to export your octopress files to Ghost. You will still need to check your data but it will give you a head start. Feel free to fork and optimize the script for your purpose.

The following should be considered:

  1. You need to execute the script in the source/_posts directory
  2. You need to manually copy all the images to /var/www/ghost/content/images
  3. Images with external URLs are not handled
  4. Blockquotes have their issues
  5. Lists are not exported correctly

For the content I had to migrate it was a good compromise between automation and manual checking and corrections.

Hope this helps anyone ;-)

#!/usr/bin/env ruby
require 'json'
require 'yaml'
require 'active_support/core_ext'
export_data = {
meta: {
version: "000"
},
data: {
posts: [],
tags: [],
posts_tags: []
}
}
class Tag
class << self
def ids
@ids ||= 2000.step(1_000_000).to_enum
end
def next_id
ids.next
end
def [](tag_name)
repository[tag_name] ||= Tag.new(tag_name)
end
def repository
@repository ||= {}
end
end
attr_reader :name, :id
def initialize(name)
@name = name
@id = Tag.next_id
end
def slug
name.parameterize
end
def to_json(*args)
{
id: id,
name: name,
slug: slug
}
end
end
class Post
class << self
def next_id
ids.next
end
def ids
@ids ||= 1000.step(1_000_000).to_enum
end
end
attr_reader :id, :tags
def initialize(raw)
@metadata = YAML.load raw
@content = raw.split('---').last.strip
@id = Post.next_id
@tags = [@metadata["categories"]].flatten.collect { |c_name| Tag[c_name] }
end
def title
@metadata["title"]
end
def slug
title.parameterize
end
def content
remove_more
fix_images
strip_newlines
fix_blockquotes
@content
end
def timestamp
@metadata["date"].to_time.to_i * 1000
end
def as_json(*args)
{
id: id,
title: title,
slug: slug,
markdown: content,
image: nil,
featured: 0,
page: 0,
status: "published",
language: "en_US",
author_id: 1,
created_at: timestamp,
created_by: 1,
updated_at: timestamp,
updated_by: 1,
published_at: timestamp,
published_by: 1
}
end
private
def remove_more
@content.gsub! '<!-- more -->', ''
end
def fix_images
@content.gsub!(/\{% img.*?(\/.*?) \d+ \d+\s?(.*?) %}/, '![\2](\1)')
@content.gsub!('images', 'content/images')
end
def strip_newlines
@content = @content.strip.gsub(/(.)\n(.)/, '\1 \2')
end
def fix_blockquotes
@content.gsub!(/{% blockquote %}(.*?){% endblockquote %}/, '> \1')
end
end
tag_ids = 3000.step(1_000_000).to_enum
posts = Dir.glob("*.{markdown,md}")
posts.each do |post_file|
post = Post.new File.read post_file
export_data[:data][:posts] << post.as_json
post.tags.each do |tag|
export_data[:data][:posts_tags] << {
id: tag_ids.next,
post_id: post.id,
tag_id: tag.id
}
end
end
export_data[:data][:tags] = Tag.repository.values
puts export_data.to_json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment