var fs = require('fs'),
  ejs = require('ejs');

function titlefy(fileName) {
  // Eww, gross. I'm so bad.
  var string = fileName.substring(0, 1).toUpperCase() + fileName.substring(1);
  return string.replace(/-([a-z])/ig, function (all, letter) {
      return ' ' + letter.toUpperCase();
  }).replace(/ Of /g, ' of ').replace(/ And /g, ' and ').replace(/ The /g, ' the ')
    .replace(/ Or /g, ' or ').replace(/ For /g, ' for ').replace(/ To /g, ' to ')
    .replace(/ At /g, ' at ').replace(/ In /g, ' in ').replace(/ A /g, ' a ')
    .replace(/ With /g, ' with ').replace(/ But /g, ' but ').replace(/-/g, ' ');
}

function renderBlogs(uncanny) {
  fs.readFile(uncanny.source + 'blogs/layout.ejs', 'utf8', function (err, template) {
    uncanny.uncanny.blogs.forEach(function (blog) {
      var blogPage = ejs.render(template, {
        filename: uncanny.source + 'blogs/layout.ejs',
        uncanny: uncanny.uncanny,
        blog: blog
      });

      fs.writeFile(uncanny.target + 'blogs/' + blog.name + '.html', blogPage);
    });
  });
}

function rebuildUncanny(uncanny, callback) {
  ['blogs', 'scripts', 'images', 'styles', 'templates'].forEach(function (directory) {
    uncanny.uncanny[directory] = [];

    if (directory == 'blogs') {
      fs.readdir(uncanny.source + directory, function (err, files) {
        files.forEach(function (file) {
          var blogDate = file.match(uncanny.blogDateExtract);
          if (blogDate) {
            var blogName = file.replace(uncanny.blogDateRegEx, '').substring(1).replace(/\.md$/, '');
            var blogContent = fs.readFileSync(uncanny.target + 'blogs/' + blogName + '.htm', 'utf8');

            var blogObject = {
              "year": blogDate[1],
              "month": blogDate[2],
              "day": blogDate[3],
              "name": blogName,
              "title": titlefy(blogName),
              "target": "/blogs/" + blogName + ".html",
              "content": blogContent,
              "source": file
            };

            uncanny.uncanny.blogs.push(blogObject);
          }
        });
        uncanny.uncanny.blogs = uncanny.uncanny.blogs.reverse();
        renderBlogs(uncanny);
      });
    } else {
      fs.readdir(uncanny.target + directory, function (err, files) {
        files.forEach(function (file) {
          uncanny.uncanny[directory].push(file);
        });
      });
    }
  });
  callback && callback();
}

function recompile(uncanny, directory, callback) {
  fs.readdir(uncanny.source + directory, function (err, files) {

    files.forEach(function (file) {
      var targetFile = uncanny.source + directory + (directory !== '' ? '/' + file : file);
      fs.stat(targetFile, function (err, stats) {
        if (!stats.isDirectory()) {
          uncanny.directories[directory].recompile(file);
        }
      });
    });

    callback && callback(directory);

  });
}

function bootstrap(uncanny, callback) {
  uncanny.customDirs.concat(['blogs', 'scripts', 'styles', 'images', 'templates']).forEach(function (directory) {
    if (!fs.existsSync(uncanny.source + directory)) { fs.mkdirSync(uncanny.source + directory); }
    if (!fs.existsSync(uncanny.target + directory)) { fs.mkdirSync(uncanny.target + directory); }
  });

  callback && callback();
}

function fixBlogName(uncanny, blogName) {
  var blogDate = new Date(),
    month = ('0' + (blogDate.getUTCMonth() + 1)).slice(-2),
    day = ('0' + blogDate.getUTCDate()).slice(-2),
    year = blogDate.getUTCFullYear(),
    newBlogName = [year, month, day, blogName].join('-');
  fs.rename(uncanny.source + 'blogs/' + blogName, uncanny.source + 'blogs/' + newBlogName);
}

exports.fixBlogName = fixBlogName;
exports.rebuildUncanny = rebuildUncanny;
exports.bootstrap = bootstrap;
exports.recompile = recompile;

@@ -639,16 +639,26 @@
 (uncanny
+, callback
 ) %7B%0A  fs
@@ -968,24 +968,28 @@
 fs.writeFile
+Sync
 (uncanny.tar
@@ -1045,16 +1045,44 @@
     %7D);%0A
+    callback && callback();%0A
   %7D);%0A%7D%0A
@@ -1580,14 +1580,15 @@
 md$/
+i
 , '')
-;
+,
 %0A   
@@ -1600,25 +1600,135 @@
     
-var blogContent =
+  contentRendered = fs.existsSync(uncanny.target + 'blogs/' + blogName + '.htm'),%0A              blogContent = contentRendered ?
  fs.
@@ -1794,19 +1794,24 @@
  'utf8')
-;%0A%0A
+ : '',%0A 
         
@@ -1810,27 +1810,24 @@
             
-var
  blogObject 
@@ -1830,16 +1830,18 @@
 ect = %7B%0A
+  
         
@@ -1881,16 +1881,18 @@
         
+  
 %22month%22:
@@ -1919,16 +1919,18 @@
         
+ 
+ 
 %22day%22: b
@@ -1955,16 +1955,18 @@
         
+  
 %22name%22: 
@@ -1989,16 +1989,18 @@
         
+ 
+ 
 %22title%22:
@@ -2019,16 +2019,18 @@
 gName),%0A
+  
         
@@ -2091,16 +2091,18 @@
         
+ 
+ 
 %22content
@@ -2131,16 +2131,18 @@
         
+  
 %22source%22
@@ -2148,16 +2148,18 @@
 %22: file%0A
+  
         
@@ -2214,24 +2214,126 @@
 logObject);%0A
+            if (!contentRendered) %7B renderBlogs(uncanny, function () %7B rebuildUncanny(uncanny); %7D); %7D%0A
           %7D%0A

this is ugly