UNPKG

html-to-json-converter

Version:

Converts html contents to json object. Compile html files and wrap it all in a single json file.

256 lines (162 loc) 5.79 kB
const glob = require('glob'); const fs = require('fs'); const path = require("path"); const frontMatter = require('front-matter'); const revHash = require('rev-hash'); const DIRECTIVE_REGEX = /^(.*=\s*([\w\.\*\/-]+)\s*:\s*([\w\.\*\/-]+\.html?\s*))$/gm; class Processor { constructor (options) { this.options = options; this.content_output = {}; } handle (contents, tpl_path, output) { let results, matches, include_paths = false; // Parse template group to get individual // html template path listed inside while (matches = DIRECTIVE_REGEX.exec(contents)) { let relative_path = path.dirname(tpl_path), html_path = path.join(relative_path, matches[3].replace(/['"]/g, '')).trim(), key_variable = matches[2] ; let file_matches = []; // Check if include path is set // Use include path as base relative path // for each html template path let include_paths = this.options.include_paths; if (this.options.include_paths) { if (typeof include_paths == "string") { // Arrayfy the string include_paths = [include_paths]; } include_paths.forEach((item) => { let include_path = path.join(item, matches[3].replace(/['"]/g, '')).trim(); if (fs.existsSync(include_path)) { let res = glob.sync(include_path, {mark: true}); file_matches = file_matches.concat(res); } }); } else { results = glob.sync(html_path, {mark: true}); file_matches = file_matches.concat(results); } try { file_matches.forEach((i) => { let content = Processor.extractContents(i); let key = (key_variable.trim() === '*') ? Processor.keyVariable(i) : key_variable; this.content_output[key] = content; }); } catch (e) { console.log(e); } } return this.content_output; } static keyVariable(path) { let n = path.split('.'); n.pop(); let nLast = n.pop(), nArr = []; if (nLast.indexOf('/') >= 0) { nArr = nLast.split('/') } else { nArr = nLast.split('\\') } return nArr.pop(); } static extractContents (path) { if (fs.existsSync(path)) { let bufferContents = fs.readFileSync(path), parsed = frontMatter(bufferContents.toString().replace(/\s+/g, ' ')); return parsed.body; } else { throw new Error('File not found: ' + path); } } } /** * HTML to JSON Service * @param config * @constructor */ function HtmlToJson (config) { this.src = config.src; this.dest = config.dest; this.prefix = config.prefix; this.options = config.options; if (!fs.existsSync(this.dest)){ fs.mkdirSync(this.dest); } } HtmlToJson.prototype = { templates () { return new Promise((resolve, reject) => { glob(this.src, { realpath: true }, (er, files) => { resolve (files); }); }); }, compile () { this.templates() .then(this.readGroup.bind(this)); }, yield () { return new Promise((resolve, reject) => { this.templates() .then((files) => { this.readGroup(files, (content) => { resolve(content); }); }); }); }, readGroup (files, cb) { if (!Array.isArray(files)) { throw Error('Template file is invalid'); } let response = {}; let rev = {}; files.forEach((i) => { let contents = fs.readFileSync(i, 'utf8'), processor = new Processor(this.options), content_output = processor.handle(contents, i), name = Processor.keyVariable(i), ext = '.json' ; if (typeof cb !== 'function') { content_output = JSON.stringify(content_output); let hash = revHash(content_output), versioned; if (this.options.as_variable) { content_output = "var " + name + "=" + content_output; ext = '.js'; } if (this.options.with_version) { versioned = name + '-' + hash; rev[name + ext] = versioned + ext; name = versioned; } let filename = this.dest + name + ext; fs.writeFile(filename, content_output, (e) => { if (e) { console.error(e); return; } console.log(`${name} saved to ${this.dest}`); }); } else { response[name] = content_output; } }); if (typeof cb === 'function') { return cb(response); } this.generateManifest(rev); }, generateManifest (rev) { if (!this.options.with_version) return; fs.writeFile(this.dest + 'rev-manifest.json', JSON.stringify(rev), (e) => { if (e) { console.error(e); return; } console.log(`Manifest file has been created`); }); } }; module.exports = HtmlToJson;