UNPKG

mini-site-generator

Version:
215 lines (191 loc) 5.89 kB
const fs = require('fs'); const path = require('path'); const minify = require('html-minifier').minify; const minOps = {collapseWhitespace: true}; const filters = ['node_modules']; let puts = []; const defaultPuts = [{in:'./', out:'./'}]; function testPut(put, label){ if (put.substr(put.length - 1) !== '/') { throw new Error('Mini Site Generator: ' +label+ ' should end with a "/" Got:' +put); } return put; } for (let j = 0; j < process.argv.length; j++) { //if we find an -io, the next 2 args should be for us! input output! if (process.argv[j] == '-io') { var input = makePathAbsolute(testPut(process.argv[j + 1], 'input')); var output = makePathAbsolute(testPut(process.argv[j + 2], 'output')); puts.push({ in: input, out: output }); j+=2; } } if (puts.length == 0) { puts = defaultPuts; } function errorHandler(err){ if (err) { console.log('err', err); } } /** * Takes an address * Returns true if that address points to a folder */ function isDirectory(sourceAddres){ return fs.lstatSync(sourceAddres).isDirectory(); } /** * Takes an array of addresses (files / folders / anything!) * Returns an array of page addresses */ function pages(addresses){ var pages = []; addresses.forEach(function(address){ if (address.indexOf('.page.js') !== -1) { pages.push(address); } }); return pages; } /** * Takes an array of addresses (files / folders / anything!) * Returns an array of folder addresses */ function folders(addresses){ var folders = []; addresses.forEach(function(address){ if (isDirectory(address)){ folders.push(address + '/'); } }); return folders; } /** * Takes an address of a folder * Returns an array of the items within that folder */ function contents(dir){ return fs.readdirSync(dir);; } /** * Takes an array of items (strings) * Returns all those that do not match filters */ function filterContents(items, filters){ var filteredItems = []; items.forEach(function(item){ var didPass = true; filters.forEach(function(filter){ if (filter === item) { didPass = false; } }); if (didPass) { filteredItems.push(item); } }); return filteredItems; } /** * Takes an address (dir) and an array of items (files / folders) * Returns an array of addresses (for each item) */ function contentAddresses(dir, items){ var returnAdds = []; items.forEach(function(item){ returnAdds.push(path.resolve(dir, item)); }); return returnAdds; } /** * Takes a page filename * Returns the dist filename */ function srcToDistName(srcFileName){ return srcFileName.replace('.page.js', '.html'); } /** * Takes a source address (meant for pages) * Returns the dist address */ function srcToDistAddress(srcAddress, siteConfig){ return srcAddress.replace(siteConfig.in, siteConfig.out); } /** * Takes the address of a page src * Returns the markup generated by said page src */ function generateMarkup(pageAddress){ var generator = require(pageAddress); return minify(generator(), minOps); } function makePathAbsolute(relativePath){ const absPath = path.resolve(relativePath); return absPath; } //=================================================== Leaving pure functions behind now //=================================================== Moving into the land of flow control /** * Takes an array of src page addresses and the site configuration object * Creates the dist address, generates the dist markup, saves the markup into the dist address */ function buildPages(pageAddressList, siteConfig){ pageAddressList.forEach(function(srcPageAddress){ var distFilename = srcToDistName(srcPageAddress); var distFileAddress = srcToDistAddress(distFilename, siteConfig); fs.writeFile(distFileAddress, generateMarkup(srcPageAddress), errorHandler); }); } /** * Takes a folder address * Makes it if it doesn't exist already */ function ensureFolderAddress(folderAddress){ if (!fs.existsSync(folderAddress)) { fs.mkdirSync(folderAddress); } return folderAddress; } /** * Recursivly steps through all the child folders * Takes a folder address (dir) * Gets the pages in the given dir and runs the page builder on them * Gets the folders within the given dir * Passes each folder to itself. */ function stepIntoDir(dir, siteConfig){ var dirContents = filterContents(contents(dir), filters); var pageList = pages(dirContents); if (pageList.length > 0) { ensureFolderAddress(srcToDistAddress(dir, siteConfig)); } var pageAddressList = contentAddresses(dir, pageList); buildPages(pageAddressList, siteConfig); var fullAddressList = contentAddresses(dir, dirContents); var folderAddressList = folders(fullAddressList); folderAddressList.forEach(function(folderAddress){ stepIntoDir(folderAddress, siteConfig); }); }; //stop the string template literal html tag from throwing an undefined if (typeof html == 'undefined') { html = function(strings, ...keys){ let returnString = ''; strings.forEach(function(str, i){ returnString += str; if (typeof keys[i] !== 'undefined') { returnString += keys[i]; } }); return returnString; } } /** * Iterate over every given input / output! * This is the beginning :) */ puts.forEach(function(put){ stepIntoDir(put.in, put); });