-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
466 additions
and
11 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
GEM | ||
remote: http://rubygems.org/ | ||
specs: | ||
activemodel (3.2.1) | ||
activesupport (= 3.2.1) | ||
builder (~> 3.0.0) | ||
activesupport (3.2.1) | ||
i18n (~> 0.6) | ||
multi_json (~> 1.0) | ||
archive-tar-minitar (0.5.2) | ||
builder (3.0.0) | ||
columnize (0.3.6) | ||
diff-lcs (1.1.3) | ||
git (1.2.5) | ||
i18n (0.6.0) | ||
jeweler (1.6.4) | ||
bundler (~> 1.0) | ||
git (>= 1.2.5) | ||
rake | ||
linecache19 (0.5.12) | ||
ruby_core_source (>= 0.1.4) | ||
multi_json (1.0.4) | ||
rake (0.9.2.2) | ||
rspec (2.3.0) | ||
rspec-core (~> 2.3.0) | ||
rspec-expectations (~> 2.3.0) | ||
rspec-mocks (~> 2.3.0) | ||
rspec-core (2.3.1) | ||
rspec-expectations (2.3.0) | ||
diff-lcs (~> 1.1.2) | ||
rspec-mocks (2.3.0) | ||
ruby-debug-base19 (0.11.25) | ||
columnize (>= 0.3.1) | ||
linecache19 (>= 0.5.11) | ||
ruby_core_source (>= 0.1.4) | ||
ruby-debug19 (0.11.6) | ||
columnize (>= 0.3.1) | ||
linecache19 (>= 0.5.11) | ||
ruby-debug-base19 (>= 0.11.19) | ||
ruby_core_source (0.1.5) | ||
archive-tar-minitar (>= 0.5.2) | ||
simplecov (0.5.4) | ||
multi_json (~> 1.0.3) | ||
simplecov-html (~> 0.5.3) | ||
simplecov-html (0.5.3) | ||
|
||
PLATFORMS | ||
ruby | ||
|
||
DEPENDENCIES | ||
activemodel | ||
bundler (~> 1.0.0) | ||
jeweler (~> 1.6.4) | ||
rspec (~> 2.3.0) | ||
ruby-debug19 | ||
simplecov |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module MovableTypeFormat | ||
autoload :Collection, "movable_type_format/collection" | ||
autoload :Entry, "movable_type_format/entry" | ||
autoload :Field, "movable_type_format/field" | ||
autoload :Next, "movable_type_format/next" | ||
autoload :Parser, "movable_type_format/parser" | ||
autoload :Section, "movable_type_format/section" | ||
extend Parser | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module MovableTypeFormat | ||
class Collection < Array | ||
def inspect | ||
to_mt | ||
end | ||
|
||
def to_mt | ||
map{|e| e.to_mt}.join | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
module MovableTypeFormat | ||
class Entry | ||
DELIMITER = "--------\n".freeze | ||
attr_accessor :sections | ||
def self.build_by_sections(sections) | ||
entry = new | ||
entry.sections = sections | ||
entry | ||
end | ||
|
||
def inspect | ||
to_mt | ||
end | ||
|
||
def to_mt | ||
sections.to_mt + DELIMITER | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
require "active_model" | ||
require "time" | ||
require "date" | ||
module MovableTypeFormat | ||
class Field | ||
KEYS = [ | ||
"AUTHOR", "TITLE", "BASENAME", "STATUS", "ALLOW", "COMMENTS", "ALLOW PINGS", | ||
"CONVERT BREAKS", "PRIMARY CATEGORY", "CATEGORY", "DATE", "TAGS", "NO ENTRY", | ||
"AUTHOR", "EMAIL", "URL", "IP", "DATE", # for COMMENT | ||
"TITLE", "URL", "IP", "BLOG NAME", "DATE", # for PING | ||
].uniq.freeze | ||
STATUS_VALUES = %w(draft publish future) | ||
ALLOW_COMMENTS_VALUES = %w(0 1) | ||
CONVERT_BREAKS_VALUES = %w(0 1 markdown markdown_with_smartypants richtext textile_2) | ||
DATE_REGEXP = %r{\A(\d\d)/(\d\d)/(\d\d\d\d) (\d\d):(\d\d):(\d\d)( AM| PM)?\z} | ||
DATE_FORMAT = "%m/%d/%Y %H:%M:%S" | ||
|
||
include ActiveModel::Validations | ||
attr_accessor :key, :value | ||
validates :key, presence: true | ||
validates :value, presence: true | ||
|
||
validate do | ||
if key | ||
if KEYS.include?(key) || custom_field? | ||
validate_value | ||
else | ||
errors.add(:key, :format) | ||
end | ||
end | ||
end | ||
|
||
def initialize(key = nil, value = nil) | ||
@key, @value = key, value | ||
end | ||
|
||
def value | ||
case key | ||
when "DATE" | ||
case @value | ||
when Date, Time | ||
@value | ||
else | ||
parse_date @value | ||
end | ||
when "TAGS" | ||
case @value | ||
when Array | ||
@value | ||
else | ||
parse_tags @value | ||
end | ||
else | ||
@value | ||
end | ||
end | ||
|
||
def inspect | ||
to_mt | ||
end | ||
|
||
def custom_field? | ||
key && key =~ /\ACF50_.+\z/ | ||
end | ||
|
||
def to_mt | ||
case key | ||
when "DATE" | ||
case value | ||
when Date, Time | ||
"#{key}: #{value.strftime(DATE_FORMAT)}\n" | ||
else | ||
time = parse_date(value) | ||
"#{key}: #{time.strftime(DATE_FORMAT)}\n" | ||
end | ||
when "TAGS" | ||
case value | ||
when Array | ||
tags = value.map{|tag| | ||
tag = %{"#{tag}"} if tag =~ / / | ||
tag | ||
}.join(",") | ||
"#{key}: #{tags}\n" | ||
else | ||
"#{key}: #{value}\n" | ||
end | ||
else | ||
"#{key}: #{value}\n" | ||
end | ||
end | ||
|
||
private | ||
def validate_value | ||
return unless value | ||
case key | ||
when "STATUS" | ||
unless STATUS_VALUES.include?(value.downcase) | ||
errors.add(:value, :inclusion) | ||
end | ||
when "ALLOW COMMENTS" | ||
unless ALLOW_COMMENTS_VALUES.include?(value.to_s) | ||
errors.add(:value, :inclusion) | ||
end | ||
when "CONVERT BREAKS" | ||
unless CONVERT_BREAKS_VALUES.include?(value.to_s) | ||
errors.add(:value, :inclusion) | ||
end | ||
when "DATE" | ||
unless value.is_a?(Date) || value.is_a?(Time) || value =~ DATE_REGEXP | ||
errors.add(:value, :format) | ||
end | ||
end | ||
end | ||
|
||
def parse_date(string) | ||
return unless string | ||
string =~ DATE_REGEXP | ||
m, d, y, h, min, s, am_pm = $~.captures | ||
if am_pm == " PM" | ||
h = h.to_i + 12 | ||
end | ||
Time.new(y.to_i, m.to_i, d.to_i, h.to_i, min.to_i, s.to_i) | ||
end | ||
|
||
def parse_tags(string) | ||
return unless string | ||
string.split(",").map{|tag| | ||
tag =~ /\A"(.+)"\z/ ? $1 : tag | ||
} | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Extend Enumerator | ||
module MovableTypeFormat | ||
module Next | ||
def next_if_exists | ||
self.next | ||
rescue StopIteration | ||
end | ||
|
||
def next? | ||
!!self.peek | ||
rescue StopIteration | ||
false | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
module MovableTypeFormat | ||
module Parser | ||
module_function | ||
def parse_file(file) | ||
end | ||
|
||
def parse(string) | ||
lines = string.lines | ||
lines.extend Next | ||
|
||
entries = Collection.new | ||
|
||
while lines.next? | ||
entries << parse_entry(lines) | ||
end | ||
|
||
entries | ||
end | ||
|
||
def parse_entry(lines) | ||
sections = Collection.new | ||
current_field = nil | ||
|
||
while lines.next? | ||
case lines.peek | ||
when "--------\n" | ||
lines.next | ||
break | ||
else | ||
sections << parse_section(lines) | ||
end | ||
end | ||
|
||
Entry.build_by_sections sections | ||
end | ||
|
||
def parse_section(lines) | ||
section = Section.new | ||
context = :head # :fields, :body | ||
|
||
while line = lines.next_if_exists | ||
case line | ||
when /^([A-Z0-9 ]+):$/ | ||
# section name or single line field | ||
key = $1 | ||
case context | ||
when :head | ||
section.name = key | ||
context = :fields | ||
else | ||
section.fields << Field.new(key) | ||
end | ||
when /^([A-Z0-9 ]+): (.+)$/ | ||
# single line field or body | ||
key, value = $~.captures | ||
case context | ||
when :head, :fields | ||
section.fields << Field.new(key, value) | ||
context = :fields | ||
else | ||
section.body ||= "" | ||
section.body << line | ||
context = :body | ||
end | ||
when "-----\n" | ||
# end of section | ||
return section | ||
else | ||
section.body ||= "" | ||
section.body << line | ||
context = :body | ||
end | ||
end | ||
section | ||
end | ||
end | ||
end |
Oops, something went wrong.