fagiani-jekyll 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. data/History.txt +284 -0
  2. data/LICENSE +21 -0
  3. data/README.textile +41 -0
  4. data/Rakefile +159 -0
  5. data/bin/jekyll +192 -0
  6. data/cucumber.yml +1 -0
  7. data/features/create_sites.feature +94 -0
  8. data/features/embed_filters.feature +60 -0
  9. data/features/markdown.feature +30 -0
  10. data/features/pagination.feature +27 -0
  11. data/features/permalinks.feature +65 -0
  12. data/features/post_data.feature +153 -0
  13. data/features/site_configuration.feature +126 -0
  14. data/features/site_data.feature +82 -0
  15. data/features/step_definitions/jekyll_steps.rb +145 -0
  16. data/features/support/env.rb +16 -0
  17. data/jekyll.gemspec +140 -0
  18. data/lib/jekyll.rb +125 -0
  19. data/lib/jekyll/albino.rb +120 -0
  20. data/lib/jekyll/converter.rb +50 -0
  21. data/lib/jekyll/converters/identity.rb +22 -0
  22. data/lib/jekyll/converters/markdown.rb +113 -0
  23. data/lib/jekyll/converters/textile.rb +33 -0
  24. data/lib/jekyll/convertible.rb +98 -0
  25. data/lib/jekyll/core_ext.rb +52 -0
  26. data/lib/jekyll/errors.rb +6 -0
  27. data/lib/jekyll/filters.rb +53 -0
  28. data/lib/jekyll/generator.rb +7 -0
  29. data/lib/jekyll/generators/pagination.rb +87 -0
  30. data/lib/jekyll/layout.rb +36 -0
  31. data/lib/jekyll/migrators/csv.rb +26 -0
  32. data/lib/jekyll/migrators/drupal.rb +86 -0
  33. data/lib/jekyll/migrators/marley.rb +53 -0
  34. data/lib/jekyll/migrators/mephisto.rb +79 -0
  35. data/lib/jekyll/migrators/mt.rb +77 -0
  36. data/lib/jekyll/migrators/textpattern.rb +50 -0
  37. data/lib/jekyll/migrators/typo.rb +49 -0
  38. data/lib/jekyll/migrators/wordpress.com.rb +38 -0
  39. data/lib/jekyll/migrators/wordpress.rb +56 -0
  40. data/lib/jekyll/page.rb +134 -0
  41. data/lib/jekyll/plugin.rb +76 -0
  42. data/lib/jekyll/post.rb +244 -0
  43. data/lib/jekyll/site.rb +273 -0
  44. data/lib/jekyll/static_file.rb +75 -0
  45. data/lib/jekyll/tags/highlight.rb +73 -0
  46. data/lib/jekyll/tags/include.rb +37 -0
  47. data/test/helper.rb +34 -0
  48. data/test/source/.htaccess +8 -0
  49. data/test/source/_includes/sig.markdown +3 -0
  50. data/test/source/_layouts/default.html +27 -0
  51. data/test/source/_layouts/simple.html +1 -0
  52. data/test/source/_posts/2008-02-02-not-published.textile +8 -0
  53. data/test/source/_posts/2008-02-02-published.textile +8 -0
  54. data/test/source/_posts/2008-10-18-foo-bar.textile +8 -0
  55. data/test/source/_posts/2008-11-21-complex.textile +8 -0
  56. data/test/source/_posts/2008-12-03-permalinked-post.textile +9 -0
  57. data/test/source/_posts/2008-12-13-include.markdown +8 -0
  58. data/test/source/_posts/2009-01-27-array-categories.textile +10 -0
  59. data/test/source/_posts/2009-01-27-categories.textile +7 -0
  60. data/test/source/_posts/2009-01-27-category.textile +7 -0
  61. data/test/source/_posts/2009-01-27-empty-categories.textile +7 -0
  62. data/test/source/_posts/2009-01-27-empty-category.textile +7 -0
  63. data/test/source/_posts/2009-03-12-hash-#1.markdown +6 -0
  64. data/test/source/_posts/2009-05-18-empty-tag.textile +6 -0
  65. data/test/source/_posts/2009-05-18-empty-tags.textile +6 -0
  66. data/test/source/_posts/2009-05-18-tag.textile +6 -0
  67. data/test/source/_posts/2009-05-18-tags.textile +9 -0
  68. data/test/source/_posts/2009-06-22-empty-yaml.textile +3 -0
  69. data/test/source/_posts/2009-06-22-no-yaml.textile +1 -0
  70. data/test/source/_posts/2010-01-08-triple-dash.markdown +5 -0
  71. data/test/source/_posts/2010-01-09-date-override.textile +7 -0
  72. data/test/source/_posts/2010-01-09-time-override.textile +7 -0
  73. data/test/source/_posts/2010-01-09-timezone-override.textile +7 -0
  74. data/test/source/_posts/2010-01-16-override-data.textile +4 -0
  75. data/test/source/about.html +6 -0
  76. data/test/source/category/_posts/2008-9-23-categories.textile +6 -0
  77. data/test/source/contacts.html +5 -0
  78. data/test/source/css/screen.css +76 -0
  79. data/test/source/deal.with.dots.html +7 -0
  80. data/test/source/foo/_posts/bar/2008-12-12-topical-post.textile +8 -0
  81. data/test/source/index.html +22 -0
  82. data/test/source/sitemap.xml +32 -0
  83. data/test/source/win/_posts/2009-05-24-yaml-linebreak.markdown +7 -0
  84. data/test/source/z_category/_posts/2008-9-23-categories.textile +6 -0
  85. data/test/suite.rb +9 -0
  86. data/test/test_configuration.rb +29 -0
  87. data/test/test_core_ext.rb +66 -0
  88. data/test/test_filters.rb +53 -0
  89. data/test/test_generated_site.rb +72 -0
  90. data/test/test_kramdown.rb +23 -0
  91. data/test/test_page.rb +117 -0
  92. data/test/test_pager.rb +113 -0
  93. data/test/test_post.rb +396 -0
  94. data/test/test_rdiscount.rb +18 -0
  95. data/test/test_site.rb +186 -0
  96. data/test/test_tags.rb +127 -0
  97. metadata +332 -0
@@ -0,0 +1,36 @@
1
+ module Jekyll
2
+
3
+ class Layout
4
+ include Convertible
5
+
6
+ attr_accessor :site
7
+ attr_accessor :ext
8
+ attr_accessor :data, :content
9
+
10
+ # Initialize a new Layout.
11
+ # +site+ is the Site
12
+ # +base+ is the String path to the <source>
13
+ # +name+ is the String filename of the post file
14
+ #
15
+ # Returns <Page>
16
+ def initialize(site, base, name)
17
+ @site = site
18
+ @base = base
19
+ @name = name
20
+
21
+ self.data = {}
22
+
23
+ self.process(name)
24
+ self.read_yaml(base, name)
25
+ end
26
+
27
+ # Extract information from the layout filename
28
+ # +name+ is the String filename of the layout file
29
+ #
30
+ # Returns nothing
31
+ def process(name)
32
+ self.ext = File.extname(name)
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,26 @@
1
+ module Jekyll
2
+ module CSV
3
+ #Reads a csv with title, permalink, body, published_at, and filter.
4
+ #It creates a post file for each row in the csv
5
+ def self.process(file = "posts.csv")
6
+ FileUtils.mkdir_p "_posts"
7
+ posts = 0
8
+ FasterCSV.foreach(file) do |row|
9
+ next if row[0] == "title"
10
+ posts += 1
11
+ name = row[3].split(" ")[0]+"-"+row[1]+(row[4] =~ /markdown/ ? ".markdown" : ".textile")
12
+ File.open("_posts/#{name}", "w") do |f|
13
+ f.puts <<-HEADER
14
+ ---
15
+ layout: post
16
+ title: #{row[0]}
17
+ ---
18
+
19
+ HEADER
20
+ f.puts row[2]
21
+ end
22
+ end
23
+ "Created #{posts} posts!"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,86 @@
1
+ require 'rubygems'
2
+ require 'sequel'
3
+ require 'fileutils'
4
+ require 'yaml'
5
+
6
+ # NOTE: This converter requires Sequel and the MySQL gems.
7
+ # The MySQL gem can be difficult to install on OS X. Once you have MySQL
8
+ # installed, running the following commands should work:
9
+ # $ sudo gem install sequel
10
+ # $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
11
+
12
+ module Jekyll
13
+ module Drupal
14
+
15
+ # Reads a MySQL database via Sequel and creates a post file for each
16
+ # post in wp_posts that has post_status = 'publish'.
17
+ # This restriction is made because 'draft' posts are not guaranteed to
18
+ # have valid dates.
19
+ QUERY = "SELECT node.nid, node.title, node_revisions.body, node.created, node.status FROM node, node_revisions WHERE (node.type = 'blog' OR node.type = 'story') AND node.vid = node_revisions.vid"
20
+
21
+ def self.process(dbname, user, pass, host = 'localhost')
22
+ db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
23
+
24
+ FileUtils.mkdir_p "_posts"
25
+ FileUtils.mkdir_p "_drafts"
26
+
27
+ # Create the refresh layout
28
+ # Change the refresh url if you customized your permalink config
29
+ File.open("_layouts/refresh.html", "w") do |f|
30
+ f.puts <<EOF
31
+ <!DOCTYPE html>
32
+ <html>
33
+ <head>
34
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
35
+ <meta http-equiv="refresh" content="0;url={{ page.refresh_to_post_id }}.html" />
36
+ </head>
37
+ </html>
38
+ EOF
39
+ end
40
+
41
+ db[QUERY].each do |post|
42
+ # Get required fields and construct Jekyll compatible name
43
+ node_id = post[:nid]
44
+ title = post[:title]
45
+ content = post[:body]
46
+ created = post[:created]
47
+ time = Time.at(created)
48
+ is_published = post[:status] == 1
49
+ dir = is_published ? "_posts" : "_drafts"
50
+ slug = title.strip.downcase.gsub(/(&|&amp;)/, ' and ').gsub(/[\s\.\/\\]/, '-').gsub(/[^\w-]/, '').gsub(/[-_]{2,}/, '-').gsub(/^[-_]/, '').gsub(/[-_]$/, '')
51
+ name = time.strftime("%Y-%m-%d-") + slug + '.md'
52
+
53
+ # Get the relevant fields as a hash, delete empty fields and convert
54
+ # to YAML for the header
55
+ data = {
56
+ 'layout' => 'post',
57
+ 'title' => title.to_s,
58
+ 'created' => created,
59
+ }.delete_if { |k,v| v.nil? || v == ''}.to_yaml
60
+
61
+ # Write out the data and content to file
62
+ File.open("#{dir}/#{name}", "w") do |f|
63
+ f.puts data
64
+ f.puts "---"
65
+ f.puts content
66
+ end
67
+
68
+ # Make a file to redirect from the old Drupal URL
69
+ if is_published
70
+ FileUtils.mkdir_p "node/#{node_id}"
71
+ File.open("node/#{node_id}/index.md", "w") do |f|
72
+ f.puts "---"
73
+ f.puts "layout: refresh"
74
+ f.puts "refresh_to_post_id: /#{time.strftime("%Y/%m/%d/") + slug}"
75
+ f.puts "---"
76
+ end
77
+ end
78
+ end
79
+
80
+ # TODO: Make dirs & files for nodes of type 'page'
81
+ # Make refresh pages for these as well
82
+
83
+ # TODO: Make refresh dirs & files according to entries in url_alias table
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,53 @@
1
+ require 'yaml'
2
+ require 'fileutils'
3
+
4
+ module Jekyll
5
+ module Marley
6
+
7
+ def self.regexp
8
+ { :id => /^\d{0,4}-{0,1}(.*)$/,
9
+ :title => /^#\s*(.*)\s+$/,
10
+ :title_with_date => /^#\s*(.*)\s+\(([0-9\/]+)\)$/,
11
+ :published_on => /.*\s+\(([0-9\/]+)\)$/,
12
+ :perex => /^([^\#\n]+\n)$/,
13
+ :meta => /^\{\{\n(.*)\}\}\n$/mi # Multiline Regexp
14
+ }
15
+ end
16
+
17
+ def self.process(marley_data_dir)
18
+ raise ArgumentError, "marley dir #{marley_data_dir} not found" unless File.directory?(marley_data_dir)
19
+
20
+ FileUtils.mkdir_p "_posts"
21
+
22
+ posts = 0
23
+ Dir["#{marley_data_dir}/**/*.txt"].each do |f|
24
+ next unless File.exists?(f)
25
+
26
+ #copied over from marley's app/lib/post.rb
27
+ file_content = File.read(f)
28
+ meta_content = file_content.slice!( self.regexp[:meta] )
29
+ body = file_content.sub( self.regexp[:title], '').sub( self.regexp[:perex], '').strip
30
+
31
+ title = file_content.scan( self.regexp[:title] ).first.to_s.strip
32
+ prerex = file_content.scan( self.regexp[:perex] ).first.to_s.strip
33
+ published_on = DateTime.parse( post[:published_on] ) rescue File.mtime( File.dirname(f) )
34
+ meta = ( meta_content ) ? YAML::load( meta_content.scan( self.regexp[:meta]).to_s ) : {}
35
+ meta['title'] = title
36
+ meta['layout'] = 'post'
37
+
38
+ formatted_date = published_on.strftime('%Y-%m-%d')
39
+ post_name = File.dirname(f).split(%r{/}).last.gsub(/\A\d+-/, '')
40
+
41
+ name = "#{formatted_date}-#{post_name}"
42
+ File.open("_posts/#{name}.markdown", "w") do |f|
43
+ f.puts meta.to_yaml
44
+ f.puts "---\n"
45
+ f.puts "\n#{prerex}\n\n" if prerex
46
+ f.puts body
47
+ end
48
+ posts += 1
49
+ end
50
+ "Created #{posts} posts!"
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,79 @@
1
+ # Quickly hacked together my Michael Ivey
2
+ # Based on mt.rb by Nick Gerakines, open source and publically
3
+ # available under the MIT license. Use this module at your own risk.
4
+
5
+ require 'rubygems'
6
+ require 'sequel'
7
+ require 'fastercsv'
8
+ require 'fileutils'
9
+ require File.join(File.dirname(__FILE__),"csv.rb")
10
+
11
+ # NOTE: This converter requires Sequel and the MySQL gems.
12
+ # The MySQL gem can be difficult to install on OS X. Once you have MySQL
13
+ # installed, running the following commands should work:
14
+ # $ sudo gem install sequel
15
+ # $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
16
+
17
+ module Jekyll
18
+ module Mephisto
19
+ #Accepts a hash with database config variables, exports mephisto posts into a csv
20
+ #export PGPASSWORD if you must
21
+ def self.postgres(c)
22
+ sql = <<-SQL
23
+ BEGIN;
24
+ CREATE TEMP TABLE jekyll AS
25
+ SELECT title, permalink, body, published_at, filter FROM contents
26
+ WHERE user_id = 1 AND type = 'Article' ORDER BY published_at;
27
+ COPY jekyll TO STDOUT WITH CSV HEADER;
28
+ ROLLBACK;
29
+ SQL
30
+ command = %Q(psql -h #{c[:host] || "localhost"} -c "#{sql.strip}" #{c[:database]} #{c[:username]} -o #{c[:filename] || "posts.csv"})
31
+ puts command
32
+ `#{command}`
33
+ CSV.process
34
+ end
35
+
36
+ # This query will pull blog posts from all entries across all blogs. If
37
+ # you've got unpublished, deleted or otherwise hidden posts please sift
38
+ # through the created posts to make sure nothing is accidently published.
39
+
40
+ QUERY = "SELECT id, permalink, body, published_at, title FROM contents WHERE user_id = 1 AND type = 'Article' AND published_at IS NOT NULL ORDER BY published_at"
41
+
42
+ def self.process(dbname, user, pass, host = 'localhost')
43
+ db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
44
+
45
+ FileUtils.mkdir_p "_posts"
46
+
47
+ db[QUERY].each do |post|
48
+ title = post[:title]
49
+ slug = post[:permalink]
50
+ date = post[:published_at]
51
+ content = post[:body]
52
+ # more_content = ''
53
+
54
+ # Be sure to include the body and extended body.
55
+ # if more_content != nil
56
+ # content = content + " \n" + more_content
57
+ # end
58
+
59
+ # Ideally, this script would determine the post format (markdown, html
60
+ # , etc) and create files with proper extensions. At this point it
61
+ # just assumes that markdown will be acceptable.
62
+ name = [date.year, date.month, date.day, slug].join('-') + ".markdown"
63
+
64
+ data = {
65
+ 'layout' => 'post',
66
+ 'title' => title.to_s,
67
+ 'mt_id' => post[:entry_id],
68
+ }.delete_if { |k,v| v.nil? || v == ''}.to_yaml
69
+
70
+ File.open("_posts/#{name}", "w") do |f|
71
+ f.puts data
72
+ f.puts "---"
73
+ f.puts content
74
+ end
75
+ end
76
+
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,77 @@
1
+ # Created by Nick Gerakines, open source and publically available under the
2
+ # MIT license. Use this module at your own risk.
3
+ # I'm an Erlang/Perl/C++ guy so please forgive my dirty ruby.
4
+
5
+ require 'rubygems'
6
+ require 'sequel'
7
+ require 'fileutils'
8
+ require 'yaml'
9
+
10
+ # NOTE: This converter requires Sequel and the MySQL gems.
11
+ # The MySQL gem can be difficult to install on OS X. Once you have MySQL
12
+ # installed, running the following commands should work:
13
+ # $ sudo gem install sequel
14
+ # $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
15
+
16
+ module Jekyll
17
+ module MT
18
+ # This query will pull blog posts from all entries across all blogs. If
19
+ # you've got unpublished, deleted or otherwise hidden posts please sift
20
+ # through the created posts to make sure nothing is accidently published.
21
+ QUERY = "SELECT entry_id, entry_basename, entry_text, entry_text_more, entry_authored_on, entry_title, entry_convert_breaks FROM mt_entry"
22
+
23
+ def self.process(dbname, user, pass, host = 'localhost')
24
+ db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
25
+
26
+ FileUtils.mkdir_p "_posts"
27
+
28
+ db[QUERY].each do |post|
29
+ title = post[:entry_title]
30
+ slug = post[:entry_basename].gsub(/_/, '-')
31
+ date = post[:entry_authored_on]
32
+ content = post[:entry_text]
33
+ more_content = post[:entry_text_more]
34
+ entry_convert_breaks = post[:entry_convert_breaks]
35
+
36
+ # Be sure to include the body and extended body.
37
+ if more_content != nil
38
+ content = content + " \n" + more_content
39
+ end
40
+
41
+ # Ideally, this script would determine the post format (markdown, html
42
+ # , etc) and create files with proper extensions. At this point it
43
+ # just assumes that markdown will be acceptable.
44
+ name = [date.year, date.month, date.day, slug].join('-') + '.' + self.suffix(entry_convert_breaks)
45
+
46
+ data = {
47
+ 'layout' => 'post',
48
+ 'title' => title.to_s,
49
+ 'mt_id' => post[:entry_id],
50
+ 'date' => date
51
+ }.delete_if { |k,v| v.nil? || v == ''}.to_yaml
52
+
53
+ File.open("_posts/#{name}", "w") do |f|
54
+ f.puts data
55
+ f.puts "---"
56
+ f.puts content
57
+ end
58
+ end
59
+ end
60
+
61
+ def self.suffix(entry_type)
62
+ if entry_type.nil? || entry_type.include?("markdown")
63
+ # The markdown plugin I have saves this as "markdown_with_smarty_pants", so I just look for "markdown".
64
+ "markdown"
65
+ elsif entry_type.include?("textile")
66
+ # This is saved as "textile_2" on my installation of MT 5.1.
67
+ "textile"
68
+ elsif entry_type == "0" || entry_type.include?("richtext")
69
+ # richtext looks to me like it's saved as HTML, so I include it here.
70
+ "html"
71
+ else
72
+ # Other values might need custom work.
73
+ entry_type
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,50 @@
1
+ require 'rubygems'
2
+ require 'sequel'
3
+ require 'fileutils'
4
+
5
+ # NOTE: This converter requires Sequel and the MySQL gems.
6
+ # The MySQL gem can be difficult to install on OS X. Once you have MySQL
7
+ # installed, running the following commands should work:
8
+ # $ sudo gem install sequel
9
+ # $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
10
+
11
+ module Jekyll
12
+ module TextPattern
13
+ # Reads a MySQL database via Sequel and creates a post file for each post.
14
+ # The only posts selected are those with a status of 4 or 5, which means "live"
15
+ # and "sticky" respectively.
16
+ # Other statuses is 1 => draft, 2 => hidden and 3 => pending
17
+ QUERY = "select Title, url_title, Posted, Body, Keywords from textpattern where Status = '4' or Status = '5'"
18
+
19
+ def self.process(dbname, user, pass, host = 'localhost')
20
+ db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
21
+
22
+ FileUtils.mkdir_p "_posts"
23
+
24
+ db[QUERY].each do |post|
25
+ # Get required fields and construct Jekyll compatible name
26
+ title = post[:Title]
27
+ slug = post[:url_title]
28
+ date = post[:Posted]
29
+ content = post[:Body]
30
+
31
+ name = [date.strftime("%Y-%m-%d"), slug].join('-') + ".textile"
32
+
33
+ # Get the relevant fields as a hash, delete empty fields and convert
34
+ # to YAML for the header
35
+ data = {
36
+ 'layout' => 'post',
37
+ 'title' => title.to_s,
38
+ 'tags' => post[:Keywords].split(',')
39
+ }.delete_if { |k,v| v.nil? || v == ''}.to_yaml
40
+
41
+ # Write out the data and content to file
42
+ File.open("_posts/#{name}", "w") do |f|
43
+ f.puts data
44
+ f.puts "---"
45
+ f.puts content
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,49 @@
1
+ # Author: Toby DiPasquale <toby@cbcg.net>
2
+ require 'fileutils'
3
+ require 'rubygems'
4
+ require 'sequel'
5
+
6
+ module Jekyll
7
+ module Typo
8
+ # this SQL *should* work for both MySQL and PostgreSQL, but I haven't
9
+ # tested PostgreSQL yet (as of 2008-12-16)
10
+ SQL = <<-EOS
11
+ SELECT c.id id,
12
+ c.title title,
13
+ c.permalink slug,
14
+ c.body body,
15
+ c.published_at date,
16
+ c.state state,
17
+ COALESCE(tf.name, 'html') filter
18
+ FROM contents c
19
+ LEFT OUTER JOIN text_filters tf
20
+ ON c.text_filter_id = tf.id
21
+ EOS
22
+
23
+ def self.process dbname, user, pass, host='localhost'
24
+ FileUtils.mkdir_p '_posts'
25
+ db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
26
+ db[SQL].each do |post|
27
+ next unless post[:state] =~ /Published/
28
+
29
+ name = [ sprintf("%.04d", post[:date].year),
30
+ sprintf("%.02d", post[:date].month),
31
+ sprintf("%.02d", post[:date].day),
32
+ post[:slug].strip ].join('-')
33
+ # Can have more than one text filter in this field, but we just want
34
+ # the first one for this
35
+ name += '.' + post[:filter].split(' ')[0]
36
+
37
+ File.open("_posts/#{name}", 'w') do |f|
38
+ f.puts({ 'layout' => 'post',
39
+ 'title' => post[:title].to_s,
40
+ 'typo_id' => post[:id]
41
+ }.delete_if { |k, v| v.nil? || v == '' }.to_yaml)
42
+ f.puts '---'
43
+ f.puts post[:body].delete("\r")
44
+ end
45
+ end
46
+ end
47
+
48
+ end # module Typo
49
+ end # module Jekyll