diff options
Diffstat (limited to 'tools/blog/generate.js')
-rw-r--r-- | tools/blog/generate.js | 270 |
1 files changed, 0 insertions, 270 deletions
diff --git a/tools/blog/generate.js b/tools/blog/generate.js deleted file mode 100644 index fa101dc0d9..0000000000 --- a/tools/blog/generate.js +++ /dev/null @@ -1,270 +0,0 @@ -#!/usr/bin/env node -var fs = require('fs'); -var marked = require('marked'); -var mkdirp = require('mkdirp'); -var glob = require('glob'); -var ejs = require('ejs'); -var path = require('path'); -var semver = require('semver'); - -var input = path.resolve(process.argv[2]); -var output = path.resolve(process.argv[3]); -var template = path.resolve(process.argv[4]); -var rssTemplate = path.resolve(process.argv[5]); - -var config = { - postsPerPage: 4 -}; - -console.error("argv=%j", process.argv) - -fs.readFile(template, 'utf8', function(er, contents) { - if (er) throw er; - template = ejs.compile(contents, template); - template.filename = 'index.html'; - fs.readFile(rssTemplate, 'utf8', function(er, contents) { - if (er) throw er; - rssTemplate = ejs.compile(contents, rssTemplate); - rssTemplate.filename = 'index.xml'; - readInput(); - }); -}); - -function readInput() { - glob(input + '/**/*.md', function(er, files) { - if (er) throw er; - readFiles(files); - }); -} - -function readFiles(files) { - var n = files.length; - var data = { files: {}, feeds: {}, posts: {}}; - - files.forEach(function(file) { - fs.readFile(file, 'utf8', next(file)); - }); - - function next(file) { return function(er, contents) { - if (er) throw er; - if (contents) { - contents = parseFile(file, contents); - if (contents) { - data.files[file] = contents - } - } - if (--n === 0) { - buildOutput(data); - } - }} -} - -function parseFile(file, contents) { - var c = contents.split('\n\n'); - var head = c.shift(); - c = c.join('\n\n'); - var post = head.split('\n').reduce(function(set, kv) { - kv = kv.split(':'); - var key = kv.shift().trim(); - var val = kv.join(':').trim(); - set[key] = val; - return set; - }, {}); - if (post.status && post.status !== 'publish') return null; - post.body = c; - post.src = file; - return post; -} - -function buildPermalinks(data) { - Object.keys(data.files).forEach(function(k) { - data.posts[k] = buildPermalink(k, data.files[k]); - }); -} - -function buildPermalink(key, post) { - var data = {}; - data.pageid = post.slug; - data.title = post.title; - data.content = post.content = marked.parse(post.body); - - // Fix for chjj/marked#56 - data.content = post.content = data.content - .replace(/<a href="([^"]+)<\/a>">\1<\/a>/g, '$1'); - - data.post = post; - - if (!post.date) throw new Error('post date is required ' + post.src); - else post.date = new Date(post.date); - var d = post.date; - - var y = d.getYear() + 1900; - var m = d.getMonth() + 1; - if (m < 10) m = '0' + m; - var d = d.getDate(); - if (d < 10) d = '0' + d; - var uri = '/' + y + '/' + m + '/' + d + '/' + post.slug + '/'; - post.data = data; - post.uri = uri; - - post.permalink = data.permalink = uri; - return data; -} - -function writeFile(uri, data, templ) { - if (!templ) templ = template; - if (data.uri) - data.uri = path.join(data.uri); - uri = path.join(uri); - var contents = templ(data); - var outdir = path.join(output, uri); - mkdirp(outdir, function(er) { - if (er) throw er; - var file = path.resolve(outdir, templ.filename); - fs.writeFile(file, contents, 'utf8', function(er) { - if (er) throw er; - console.log('wrote: ', data.pageid, path.relative(process.cwd(), file)); - }); - }); -} - -// sort in reverse chronological order -// prune out any releases that are not the most recent on their branch. -function buildFeeds(data) { - // first, sort by date. - var posts = Object.keys(data.posts).map(function(k) { - return data.posts[k].post; - }).sort(function(a, b) { - a = a.date.getTime(); - b = b.date.getTime(); - return (a === b) ? 0 : a > b ? -1 : 1; - }) - - // separate release posts by release families. - var releases = posts.reduce(function(releases, post) { - if (post.category !== 'release') return releases; - var ver = semver.parse(post.version); - if (!ver) return; - var major = +ver[1]; - var minor = +ver[2]; - var patch = +ver[3]; - var family = [major, minor]; - ver = [major, minor, patch, post]; - if (family[1] % 2) family[1]++; - family = family.join('.'); - post.family = family; - releases[family] = releases[family] || []; - releases[family].push(post); - return releases; - }, {}); - - // separate by categories. - var categories = posts.reduce(function(categories, post) { - if (!post.category) return categories; - if (!categories[post.category]) { - categories[post.category] = []; - } - categories[post.category].push(post); - return categories; - }, {}); - - // paginate categories. - for (var cat in categories) { - categories[cat] = paginate(categories[cat], cat); - } - - // show all posts in main feed. - var main = posts; - - // add previous/next based on main feed. - main.forEach(function (post, i, posts) { - post.next = posts[i - 1]; - post.prev = posts[i + 1]; - }) - - // paginate each feed. - main = paginate(main, ''); - - // put previous/next links on orphaned old releases so you can get back - for (var family in releases) { - releases[family].forEach(function(post, i, family) { - if (!post.next) post.next = family[i - 1]; - if (!post.next) post.next = family[0].next; - // if (!post.next) post.next = family[0]; - - if (!post.prev) post.prev = family[i + 1]; - if (!post.prev) post.prev = family[0].prev; - }); - // paginate - releases[family] = paginate(releases[family], 'release-' + family); - } - - // paginate - data.feeds = { - main: main, - categories: categories, - releases: releases - }; -} - -function paginate(set, title) { - var pp = config.postsPerPage || 5 - var pages = []; - for (var i = 0; i < set.length; i += pp) { - pages.push(set.slice(i, i + pp)); - } - var id = title.replace(/[^a-zA-Z0-9.]+/g, '-'); - return { id: id || 'index', pageid: id, posts: set, pages: pages, title: title }; -} - -function writePermalinks(data) { - Object.keys(data.posts).forEach(function(k) { - var post = data.posts[k]; - writeFile(post.permalink, post); - }); -} - -function writeFeeds(data) { - writeFeed(data.feeds.main); - - for (var feed in data.feeds.categories) { - writeFeed(data.feeds.categories[feed]); - } - for (var feed in data.feeds.releases) { - writeFeed(data.feeds.releases[feed]); - } -} - -function writeFeed(feed) { - var title = feed.title; - feed.pages.forEach(function(page, p, pages) { - writePaginated(feed.title, page, p, pages.length, feed.id); - }); -} - -function writePaginated(title, posts, p, total, id) { - var uri = '/' + encodeURIComponent(title) + '/'; - var d = { - title: title, - page: p, - posts: posts, - total: total, - paginated: true, - pageid: id + '-' + p, - uri: uri - }; - if (p === 0) { - writeFile(uri, d); - writeFile('/feed' + uri, d, rssTemplate); - } - writeFile(uri + p, d); - writeFile('/feed' + uri + p, d, rssTemplate); -} - -function buildOutput(data) { - buildPermalinks(data); - buildFeeds(data); - writePermalinks(data); - writeFeeds(data); -} - |