summaryrefslogtreecommitdiffstats
path: root/lib/utils
diff options
context:
space:
mode:
Diffstat (limited to 'lib/utils')
-rw-r--r--lib/utils/__tests__/git.js57
-rw-r--r--lib/utils/__tests__/location.js100
-rw-r--r--lib/utils/__tests__/path.js17
-rw-r--r--lib/utils/command.js118
-rw-r--r--lib/utils/error.js99
-rw-r--r--lib/utils/fs.js170
-rw-r--r--lib/utils/genKey.js13
-rw-r--r--lib/utils/git.js133
-rw-r--r--lib/utils/images.js60
-rw-r--r--lib/utils/location.js139
-rw-r--r--lib/utils/logger.js172
-rw-r--r--lib/utils/mergeDefaults.js16
-rw-r--r--lib/utils/path.js74
-rw-r--r--lib/utils/promise.js148
-rw-r--r--lib/utils/reducedObject.js33
-rw-r--r--lib/utils/timing.js97
16 files changed, 0 insertions, 1446 deletions
diff --git a/lib/utils/__tests__/git.js b/lib/utils/__tests__/git.js
deleted file mode 100644
index abc1ea1..0000000
--- a/lib/utils/__tests__/git.js
+++ /dev/null
@@ -1,57 +0,0 @@
-var path = require('path');
-var os = require('os');
-
-var Git = require('../git');
-
-describe('Git', function() {
-
- describe('URL parsing', function() {
-
- it('should correctly validate git urls', function() {
- // HTTPS
- expect(Git.isUrl('git+https://github.com/Hello/world.git')).toBeTruthy();
-
- // SSH
- expect(Git.isUrl('git+git@github.com:GitbookIO/gitbook.git/directory/README.md#e1594cde2c32e4ff48f6c4eff3d3d461743d74e1')).toBeTruthy();
-
- // Non valid
- expect(Git.isUrl('https://github.com/Hello/world.git')).toBeFalsy();
- expect(Git.isUrl('README.md')).toBeFalsy();
- });
-
- it('should parse HTTPS urls', function() {
- var parts = Git.parseUrl('git+https://gist.github.com/69ea4542e4c8967d2fa7.git/test.md');
-
- expect(parts.host).toBe('https://gist.github.com/69ea4542e4c8967d2fa7.git');
- expect(parts.ref).toBe(null);
- expect(parts.filepath).toBe('test.md');
- });
-
- it('should parse HTTPS urls with a reference', function() {
- var parts = Git.parseUrl('git+https://gist.github.com/69ea4542e4c8967d2fa7.git/test.md#1.0.0');
-
- expect(parts.host).toBe('https://gist.github.com/69ea4542e4c8967d2fa7.git');
- expect(parts.ref).toBe('1.0.0');
- expect(parts.filepath).toBe('test.md');
- });
-
- it('should parse SSH urls', function() {
- var parts = Git.parseUrl('git+git@github.com:GitbookIO/gitbook.git/directory/README.md#e1594cde2c32e4ff48f6c4eff3d3d461743d74e1');
-
- expect(parts.host).toBe('git@github.com:GitbookIO/gitbook.git');
- expect(parts.ref).toBe('e1594cde2c32e4ff48f6c4eff3d3d461743d74e1');
- expect(parts.filepath).toBe('directory/README.md');
- });
- });
-
- describe('Cloning and resolving', function() {
- it('should clone an HTTPS url', function() {
- var git = new Git(path.join(os.tmpdir(), 'test-git-'+Date.now()));
- return git.resolve('git+https://gist.github.com/69ea4542e4c8967d2fa7.git/test.md')
- .then(function(filename) {
- expect(path.extname(filename)).toBe('.md');
- });
- });
- });
-
-});
diff --git a/lib/utils/__tests__/location.js b/lib/utils/__tests__/location.js
deleted file mode 100644
index 822338e..0000000
--- a/lib/utils/__tests__/location.js
+++ /dev/null
@@ -1,100 +0,0 @@
-var LocationUtils = require('../location');
-
-describe('LocationUtils', function() {
- it('should correctly test external location', function() {
- expect(LocationUtils.isExternal('http://google.fr')).toBe(true);
- expect(LocationUtils.isExternal('https://google.fr')).toBe(true);
- expect(LocationUtils.isExternal('test.md')).toBe(false);
- expect(LocationUtils.isExternal('folder/test.md')).toBe(false);
- expect(LocationUtils.isExternal('/folder/test.md')).toBe(false);
- expect(LocationUtils.isExternal('data:image/png')).toBe(false);
- });
-
- it('should correctly test data:uri location', function() {
- expect(LocationUtils.isDataURI('data:image/png')).toBe(true);
- expect(LocationUtils.isDataURI('http://google.fr')).toBe(false);
- expect(LocationUtils.isDataURI('https://google.fr')).toBe(false);
- expect(LocationUtils.isDataURI('test.md')).toBe(false);
- expect(LocationUtils.isDataURI('data.md')).toBe(false);
- });
-
- it('should correctly detect anchor location', function() {
- expect(LocationUtils.isAnchor('#test')).toBe(true);
- expect(LocationUtils.isAnchor(' #test')).toBe(true);
- expect(LocationUtils.isAnchor('https://google.fr#test')).toBe(false);
- expect(LocationUtils.isAnchor('test.md#test')).toBe(false);
- });
-
- describe('.relative', function() {
- it('should resolve to a relative path (same folder)', function() {
- expect(LocationUtils.relative('links/', 'links/test.md')).toBe('test.md');
- });
-
- it('should resolve to a relative path (parent folder)', function() {
- expect(LocationUtils.relative('links/', 'test.md')).toBe('../test.md');
- });
-
- it('should resolve to a relative path (child folder)', function() {
- expect(LocationUtils.relative('links/', 'links/hello/test.md')).toBe('hello/test.md');
- });
- });
-
- describe('.flatten', function() {
- it('should remove leading slash', function() {
- expect(LocationUtils.flatten('/test.md')).toBe('test.md');
- expect(LocationUtils.flatten('/hello/cool.md')).toBe('hello/cool.md');
- });
-
- it('should remove leading slashes', function() {
- expect(LocationUtils.flatten('///test.md')).toBe('test.md');
- });
-
- it('should not break paths', function() {
- expect(LocationUtils.flatten('hello/cool.md')).toBe('hello/cool.md');
- });
- });
-
- describe('.toAbsolute', function() {
- it('should correctly transform as absolute', function() {
- expect(LocationUtils.toAbsolute('http://google.fr')).toBe('http://google.fr');
- expect(LocationUtils.toAbsolute('test.md', './', './')).toBe('test.md');
- expect(LocationUtils.toAbsolute('folder/test.md', './', './')).toBe('folder/test.md');
- });
-
- it('should correctly handle windows path', function() {
- expect(LocationUtils.toAbsolute('folder\\test.md', './', './')).toBe('folder/test.md');
- });
-
- it('should correctly handle absolute path', function() {
- expect(LocationUtils.toAbsolute('/test.md', './', './')).toBe('test.md');
- expect(LocationUtils.toAbsolute('/test.md', 'test', 'test')).toBe('../test.md');
- expect(LocationUtils.toAbsolute('/sub/test.md', 'test', 'test')).toBe('../sub/test.md');
- expect(LocationUtils.toAbsolute('/test.png', 'folder', '')).toBe('test.png');
- });
-
- it('should correctly handle absolute path (windows)', function() {
- expect(LocationUtils.toAbsolute('\\test.png', 'folder', '')).toBe('test.png');
- });
-
- it('should resolve path starting by "/" in root directory', function() {
- expect(
- LocationUtils.toAbsolute('/test/hello.md', './', './')
- ).toBe('test/hello.md');
- });
-
- it('should resolve path starting by "/" in child directory', function() {
- expect(
- LocationUtils.toAbsolute('/test/hello.md', './hello', './')
- ).toBe('test/hello.md');
- });
-
- it('should resolve path starting by "/" in child directory, with same output directory', function() {
- expect(
- LocationUtils.toAbsolute('/test/hello.md', './hello', './hello')
- ).toBe('../test/hello.md');
- });
- });
-
-});
-
-
diff --git a/lib/utils/__tests__/path.js b/lib/utils/__tests__/path.js
deleted file mode 100644
index 22bb016..0000000
--- a/lib/utils/__tests__/path.js
+++ /dev/null
@@ -1,17 +0,0 @@
-var path = require('path');
-
-describe('Paths', function() {
- var PathUtils = require('..//path');
-
- describe('setExtension', function() {
- it('should correctly change extension of filename', function() {
- expect(PathUtils.setExtension('test.md', '.html')).toBe('test.html');
- expect(PathUtils.setExtension('test.md', '.json')).toBe('test.json');
- });
-
- it('should correctly change extension of path', function() {
- expect(PathUtils.setExtension('hello/test.md', '.html')).toBe(path.normalize('hello/test.html'));
- expect(PathUtils.setExtension('hello/test.md', '.json')).toBe(path.normalize('hello/test.json'));
- });
- });
-});
diff --git a/lib/utils/command.js b/lib/utils/command.js
deleted file mode 100644
index 90a556e..0000000
--- a/lib/utils/command.js
+++ /dev/null
@@ -1,118 +0,0 @@
-var is = require('is');
-var childProcess = require('child_process');
-var spawn = require('spawn-cmd').spawn;
-var Promise = require('./promise');
-
-/**
- Execute a command
-
- @param {String} command
- @param {Object} options
- @return {Promise}
-*/
-function exec(command, options) {
- var d = Promise.defer();
-
- var child = childProcess.exec(command, options, function(err, stdout, stderr) {
- if (!err) {
- return d.resolve();
- }
-
- err.message = stdout.toString('utf8') + stderr.toString('utf8');
- d.reject(err);
- });
-
- child.stdout.on('data', function (data) {
- d.notify(data);
- });
-
- child.stderr.on('data', function (data) {
- d.notify(data);
- });
-
- return d.promise;
-}
-
-/**
- Spawn an executable
-
- @param {String} command
- @param {Array} args
- @param {Object} options
- @return {Promise}
-*/
-function spawnCmd(command, args, options) {
- var d = Promise.defer();
- var child = spawn(command, args, options);
-
- child.on('error', function(error) {
- return d.reject(error);
- });
-
- child.stdout.on('data', function (data) {
- d.notify(data);
- });
-
- child.stderr.on('data', function (data) {
- d.notify(data);
- });
-
- child.on('close', function(code) {
- if (code === 0) {
- d.resolve();
- } else {
- d.reject(new Error('Error with command "'+command+'"'));
- }
- });
-
- return d.promise;
-}
-
-/**
- Transform an option object to a command line string
-
- @param {String|number} value
- @param {String}
-*/
-function escapeShellArg(value) {
- if (is.number(value)) {
- return value;
- }
-
- value = String(value);
- value = value.replace(/"/g, '\\"');
-
- return '"' + value + '"';
-}
-
-/**
- Transform a map of options into a command line arguments string
-
- @param {Object} options
- @return {String}
-*/
-function optionsToShellArgs(options) {
- var result = [];
-
- for (var key in options) {
- var value = options[key];
-
- if (value === null || value === undefined || value === false) {
- continue;
- }
-
- if (is.bool(value)) {
- result.push(key);
- } else {
- result.push(key + '=' + escapeShellArg(value));
- }
- }
-
- return result.join(' ');
-}
-
-module.exports = {
- exec: exec,
- spawn: spawnCmd,
- optionsToShellArgs: optionsToShellArgs
-};
diff --git a/lib/utils/error.js b/lib/utils/error.js
deleted file mode 100644
index 7686779..0000000
--- a/lib/utils/error.js
+++ /dev/null
@@ -1,99 +0,0 @@
-var is = require('is');
-
-var TypedError = require('error/typed');
-var WrappedError = require('error/wrapped');
-
-
-// Enforce as an Error object, and cleanup message
-function enforce(err) {
- if (is.string(err)) err = new Error(err);
- err.message = err.message.replace(/^Error: /, '');
-
- return err;
-}
-
-// Random error wrappers during parsing/generation
-var ParsingError = WrappedError({
- message: 'Parsing Error: {origMessage}',
- type: 'parse'
-});
-var OutputError = WrappedError({
- message: 'Output Error: {origMessage}',
- type: 'generate'
-});
-
-// A file does not exists
-var FileNotFoundError = TypedError({
- type: 'file.not-found',
- message: 'No "{filename}" file (or is ignored)',
- filename: null
-});
-
-// A file cannot be parsed
-var FileNotParsableError = TypedError({
- type: 'file.not-parsable',
- message: '"{filename}" file cannot be parsed',
- filename: null
-});
-
-// A file is outside the scope
-var FileOutOfScopeError = TypedError({
- type: 'file.out-of-scope',
- message: '"{filename}" not in "{root}"',
- filename: null,
- root: null,
- code: 'EACCESS'
-});
-
-// A file is outside the scope
-var RequireInstallError = TypedError({
- type: 'install.required',
- message: '"{cmd}" is not installed.\n{install}',
- cmd: null,
- code: 'ENOENT',
- install: ''
-});
-
-// Error for nunjucks templates
-var TemplateError = WrappedError({
- message: 'Error compiling template "{filename}": {origMessage}',
- type: 'template',
- filename: null
-});
-
-// Error for nunjucks templates
-var PluginError = WrappedError({
- message: 'Error with plugin "{plugin}": {origMessage}',
- type: 'plugin',
- plugin: null
-});
-
-// Error with the book's configuration
-var ConfigurationError = WrappedError({
- message: 'Error with book\'s configuration: {origMessage}',
- type: 'configuration'
-});
-
-// Error during ebook generation
-var EbookError = WrappedError({
- message: 'Error during ebook generation: {origMessage}\n{stdout}',
- type: 'ebook',
- stdout: ''
-});
-
-module.exports = {
- enforce: enforce,
-
- ParsingError: ParsingError,
- OutputError: OutputError,
- RequireInstallError: RequireInstallError,
-
- FileNotParsableError: FileNotParsableError,
- FileNotFoundError: FileNotFoundError,
- FileOutOfScopeError: FileOutOfScopeError,
-
- TemplateError: TemplateError,
- PluginError: PluginError,
- ConfigurationError: ConfigurationError,
- EbookError: EbookError
-};
diff --git a/lib/utils/fs.js b/lib/utils/fs.js
deleted file mode 100644
index 35839a3..0000000
--- a/lib/utils/fs.js
+++ /dev/null
@@ -1,170 +0,0 @@
-var fs = require('graceful-fs');
-var mkdirp = require('mkdirp');
-var destroy = require('destroy');
-var rmdir = require('rmdir');
-var tmp = require('tmp');
-var request = require('request');
-var path = require('path');
-var cp = require('cp');
-var cpr = require('cpr');
-
-var Promise = require('./promise');
-
-// Write a stream to a file
-function writeStream(filename, st) {
- var d = Promise.defer();
-
- var wstream = fs.createWriteStream(filename);
- var cleanup = function() {
- destroy(wstream);
- wstream.removeAllListeners();
- };
-
- wstream.on('finish', function () {
- cleanup();
- d.resolve();
- });
- wstream.on('error', function (err) {
- cleanup();
- d.reject(err);
- });
-
- st.on('error', function(err) {
- cleanup();
- d.reject(err);
- });
-
- st.pipe(wstream);
-
- return d.promise;
-}
-
-// Return a promise resolved with a boolean
-function fileExists(filename) {
- var d = Promise.defer();
-
- fs.exists(filename, function(exists) {
- d.resolve(exists);
- });
-
- return d.promise;
-}
-
-// Generate temporary file
-function genTmpFile(opts) {
- return Promise.nfcall(tmp.file, opts)
- .get(0);
-}
-
-// Generate temporary dir
-function genTmpDir(opts) {
- return Promise.nfcall(tmp.dir, opts)
- .get(0);
-}
-
-// Download an image
-function download(uri, dest) {
- return writeStream(dest, request(uri));
-}
-
-// Find a filename available in a folder
-function uniqueFilename(base, filename) {
- var ext = path.extname(filename);
- filename = path.resolve(base, filename);
- filename = path.join(path.dirname(filename), path.basename(filename, ext));
-
- var _filename = filename+ext;
-
- var i = 0;
- while (fs.existsSync(filename)) {
- _filename = filename + '_' + i + ext;
- i = i + 1;
- }
-
- return Promise(path.relative(base, _filename));
-}
-
-// Create all required folder to create a file
-function ensureFile(filename) {
- var base = path.dirname(filename);
- return Promise.nfcall(mkdirp, base);
-}
-
-// Remove a folder
-function rmDir(base) {
- return Promise.nfcall(rmdir, base, {
- fs: fs
- });
-}
-
-/**
- Assert a file, if it doesn't exist, call "generator"
-
- @param {String} filePath
- @param {Function} generator
- @return {Promise}
-*/
-function assertFile(filePath, generator) {
- return fileExists(filePath)
- .then(function(exists) {
- if (exists) return;
-
- return generator();
- });
-}
-
-/**
- Pick a file, returns the absolute path if exists, undefined otherwise
-
- @param {String} rootFolder
- @param {String} fileName
- @return {String}
-*/
-function pickFile(rootFolder, fileName) {
- var result = path.join(rootFolder, fileName);
- if (fs.existsSync(result)) {
- return result;
- }
-
- return undefined;
-}
-
-/**
- Ensure that a directory exists and is empty
-
- @param {String} folder
- @return {Promise}
-*/
-function ensureFolder(rootFolder) {
- return rmDir(rootFolder)
- .fail(function() {
- return Promise();
- })
- .then(function() {
- return Promise.nfcall(mkdirp, rootFolder);
- });
-}
-
-module.exports = {
- exists: fileExists,
- existsSync: fs.existsSync,
- mkdirp: Promise.nfbind(mkdirp),
- readFile: Promise.nfbind(fs.readFile),
- writeFile: Promise.nfbind(fs.writeFile),
- assertFile: assertFile,
- pickFile: pickFile,
- stat: Promise.nfbind(fs.stat),
- statSync: fs.statSync,
- readdir: Promise.nfbind(fs.readdir),
- writeStream: writeStream,
- readStream: fs.createReadStream,
- copy: Promise.nfbind(cp),
- copyDir: Promise.nfbind(cpr),
- tmpFile: genTmpFile,
- tmpDir: genTmpDir,
- download: download,
- uniqueFilename: uniqueFilename,
- ensureFile: ensureFile,
- ensureFolder: ensureFolder,
- rmDir: rmDir
-};
diff --git a/lib/utils/genKey.js b/lib/utils/genKey.js
deleted file mode 100644
index 0650011..0000000
--- a/lib/utils/genKey.js
+++ /dev/null
@@ -1,13 +0,0 @@
-var lastKey = 0;
-
-/*
- Generate a random key
- @return {String}
-*/
-function generateKey() {
- lastKey += 1;
- var str = lastKey.toString(16);
- return '00000'.slice(str.length) + str;
-}
-
-module.exports = generateKey;
diff --git a/lib/utils/git.js b/lib/utils/git.js
deleted file mode 100644
index 6884b83..0000000
--- a/lib/utils/git.js
+++ /dev/null
@@ -1,133 +0,0 @@
-var is = require('is');
-var path = require('path');
-var crc = require('crc');
-var URI = require('urijs');
-
-var pathUtil = require('./path');
-var Promise = require('./promise');
-var command = require('./command');
-var fs = require('./fs');
-
-var GIT_PREFIX = 'git+';
-
-function Git() {
- this.tmpDir;
- this.cloned = {};
-}
-
-// Return an unique ID for a combinaison host/ref
-Git.prototype.repoID = function(host, ref) {
- return crc.crc32(host+'#'+(ref || '')).toString(16);
-};
-
-// Allocate a temporary folder for cloning repos in it
-Git.prototype.allocateDir = function() {
- var that = this;
-
- if (this.tmpDir) return Promise();
-
- return fs.tmpDir()
- .then(function(dir) {
- that.tmpDir = dir;
- });
-};
-
-// Clone a git repository if non existant
-Git.prototype.clone = function(host, ref) {
- var that = this;
-
- return this.allocateDir()
-
- // Return or clone the git repo
- .then(function() {
- // Unique ID for repo/ref combinaison
- var repoId = that.repoID(host, ref);
-
- // Absolute path to the folder
- var repoPath = path.join(that.tmpDir, repoId);
-
- if (that.cloned[repoId]) return repoPath;
-
- // Clone repo
- return command.exec('git clone '+host+' '+repoPath)
-
- // Checkout reference if specified
- .then(function() {
- that.cloned[repoId] = true;
-
- if (!ref) return;
- return command.exec('git checkout '+ref, { cwd: repoPath });
- })
- .thenResolve(repoPath);
- });
-};
-
-// Get file from a git repo
-Git.prototype.resolve = function(giturl) {
- // Path to a file in a git repo?
- if (!Git.isUrl(giturl)) {
- if (this.resolveRoot(giturl)) return Promise(giturl);
- return Promise(null);
- }
- if (is.string(giturl)) giturl = Git.parseUrl(giturl);
- if (!giturl) return Promise(null);
-
- // Clone or get from cache
- return this.clone(giturl.host, giturl.ref)
- .then(function(repo) {
- return path.resolve(repo, giturl.filepath);
- });
-};
-
-// Return root of git repo from a filepath
-Git.prototype.resolveRoot = function(filepath) {
- var relativeToGit, repoId;
-
- // No git repo cloned, or file is not in a git repository
- if (!this.tmpDir || !pathUtil.isInRoot(this.tmpDir, filepath)) return null;
-
- // Extract first directory (is the repo id)
- relativeToGit = path.relative(this.tmpDir, filepath);
- repoId = relativeToGit.split(path.sep)[0];
- if (!repoId) {
- return;
- }
-
- // Return an absolute file
- return path.resolve(this.tmpDir, repoId);
-};
-
-// Check if an url is a git dependency url
-Git.isUrl = function(giturl) {
- return (giturl.indexOf(GIT_PREFIX) === 0);
-};
-
-// Parse and extract infos
-Git.parseUrl = function(giturl) {
- var ref, uri, fileParts, filepath;
-
- if (!Git.isUrl(giturl)) return null;
- giturl = giturl.slice(GIT_PREFIX.length);
-
- uri = new URI(giturl);
- ref = uri.fragment() || null;
- uri.fragment(null);
-
- // Extract file inside the repo (after the .git)
- fileParts = uri.path().split('.git');
- filepath = fileParts.length > 1? fileParts.slice(1).join('.git') : '';
- if (filepath[0] == '/') {
- filepath = filepath.slice(1);
- }
-
- // Recreate pathname without the real filename
- uri.path(fileParts[0] + '.git');
-
- return {
- host: uri.toString(),
- ref: ref,
- filepath: filepath
- };
-};
-
-module.exports = Git;
diff --git a/lib/utils/images.js b/lib/utils/images.js
deleted file mode 100644
index 6d4b927..0000000
--- a/lib/utils/images.js
+++ /dev/null
@@ -1,60 +0,0 @@
-var Promise = require('./promise');
-var command = require('./command');
-var fs = require('./fs');
-var error = require('./error');
-
-// Convert a svg file to a pmg
-function convertSVGToPNG(source, dest, options) {
- if (!fs.existsSync(source)) return Promise.reject(new error.FileNotFoundError({ filename: source }));
-
- return command.spawn('svgexport', [source, dest])
- .fail(function(err) {
- if (err.code == 'ENOENT') {
- err = error.RequireInstallError({
- cmd: 'svgexport',
- install: 'Install it using: "npm install svgexport -g"'
- });
- }
- throw err;
- })
- .then(function() {
- if (fs.existsSync(dest)) return;
-
- throw new Error('Error converting '+source+' into '+dest);
- });
-}
-
-// Convert a svg buffer to a png file
-function convertSVGBufferToPNG(buf, dest) {
- // Create a temporary SVG file to convert
- return fs.tmpFile({
- postfix: '.svg'
- })
- .then(function(tmpSvg) {
- return fs.writeFile(tmpSvg, buf)
- .then(function() {
- return convertSVGToPNG(tmpSvg, dest);
- });
- });
-}
-
-// Converts a inline data: to png file
-function convertInlinePNG(source, dest) {
- if (!/^data\:image\/png/.test(source)) return Promise.reject(new Error('Source is not a PNG data-uri'));
-
- var base64data = source.split('data:image/png;base64,')[1];
- var buf = new Buffer(base64data, 'base64');
-
- return fs.writeFile(dest, buf)
- .then(function() {
- if (fs.existsSync(dest)) return;
-
- throw new Error('Error converting '+source+' into '+dest);
- });
-}
-
-module.exports = {
- convertSVGToPNG: convertSVGToPNG,
- convertSVGBufferToPNG: convertSVGBufferToPNG,
- convertInlinePNG: convertInlinePNG
-}; \ No newline at end of file
diff --git a/lib/utils/location.js b/lib/utils/location.js
deleted file mode 100644
index 00d8004..0000000
--- a/lib/utils/location.js
+++ /dev/null
@@ -1,139 +0,0 @@
-var url = require('url');
-var path = require('path');
-
-// Is the url an external url
-function isExternal(href) {
- try {
- return Boolean(url.parse(href).protocol) && !isDataURI(href);
- } catch(err) {
- return false;
- }
-}
-
-// Is the url an iniline data-uri
-function isDataURI(href) {
- try {
- return Boolean(url.parse(href).protocol) && (url.parse(href).protocol === 'data:');
- } catch(err) {
- return false;
- }
-}
-
-// Inverse of isExternal
-function isRelative(href) {
- return !isExternal(href);
-}
-
-// Return true if the link is an achor
-function isAnchor(href) {
- try {
- var parsed = url.parse(href);
- return !!(!parsed.protocol && !parsed.path && parsed.hash);
- } catch(err) {
- return false;
- }
-}
-
-// Normalize a path to be a link
-function normalize(s) {
- return path.normalize(s).replace(/\\/g, '/');
-}
-
-/**
- * Flatten a path, it removes the leading "/"
- *
- * @param {String} href
- * @return {String}
- */
-function flatten(href) {
- href = normalize(href);
- if (href[0] == '/') {
- href = normalize(href.slice(1));
- }
-
- return href;
-}
-
-/**
- * Convert a relative path to absolute
- *
- * @param {String} href
- * @param {String} dir: directory parent of the file currently in rendering process
- * @param {String} outdir: directory parent from the html output
- * @return {String}
- */
-function toAbsolute(_href, dir, outdir) {
- if (isExternal(_href) || isDataURI(_href)) {
- return _href;
- }
-
- outdir = outdir == undefined? dir : outdir;
-
- _href = normalize(_href);
- dir = normalize(dir);
- outdir = normalize(outdir);
-
- // Path "_href" inside the base folder
- var hrefInRoot = normalize(path.join(dir, _href));
- if (_href[0] == '/') {
- hrefInRoot = normalize(_href.slice(1));
- }
-
- // Make it relative to output
- _href = path.relative(outdir, hrefInRoot);
-
- // Normalize windows paths
- _href = normalize(_href);
-
- return _href;
-}
-
-/**
- * Convert an absolute path to a relative path for a specific folder (dir)
- * ('test/', 'hello.md') -> '../hello.md'
- *
- * @param {String} dir: current directory
- * @param {String} file: absolute path of file
- * @return {String}
- */
-function relative(dir, file) {
- var isDirectory = file.slice(-1) === '/';
- return normalize(path.relative(dir, file)) + (isDirectory? '/': '');
-}
-
-/**
- * Convert an absolute path to a relative path for a specific folder (dir)
- * ('test/test.md', 'hello.md') -> '../hello.md'
- *
- * @param {String} baseFile: current file
- * @param {String} file: absolute path of file
- * @return {String}
- */
-function relativeForFile(baseFile, file) {
- return relative(path.dirname(baseFile), file);
-}
-
-/**
- * Compare two paths, return true if they are identical
- * ('README.md', './README.md') -> true
- *
- * @param {String} p1: first path
- * @param {String} p2: second path
- * @return {Boolean}
- */
-function areIdenticalPaths(p1, p2) {
- return normalize(p1) === normalize(p2);
-}
-
-module.exports = {
- areIdenticalPaths: areIdenticalPaths,
- isDataURI: isDataURI,
- isExternal: isExternal,
- isRelative: isRelative,
- isAnchor: isAnchor,
- normalize: normalize,
- toAbsolute: toAbsolute,
- relative: relative,
- relativeForFile: relativeForFile,
- flatten: flatten
-};
diff --git a/lib/utils/logger.js b/lib/utils/logger.js
deleted file mode 100644
index 6fac92b..0000000
--- a/lib/utils/logger.js
+++ /dev/null
@@ -1,172 +0,0 @@
-var is = require('is');
-var util = require('util');
-var color = require('bash-color');
-var Immutable = require('immutable');
-
-var LEVELS = Immutable.Map({
- DEBUG: 0,
- INFO: 1,
- WARN: 2,
- ERROR: 3,
- DISABLED: 10
-});
-
-var COLORS = Immutable.Map({
- DEBUG: color.purple,
- INFO: color.cyan,
- WARN: color.yellow,
- ERROR: color.red
-});
-
-function Logger(write, logLevel) {
- if (!(this instanceof Logger)) return new Logger(write, logLevel);
-
- this._write = write || function(msg) {
- if(process.stdout) {
- process.stdout.write(msg);
- }
- };
- this.lastChar = '\n';
-
- this.setLevel(logLevel || 'info');
-
- // Create easy-to-use method like "logger.debug.ln('....')"
- LEVELS.forEach(function(level, levelKey) {
- if (levelKey === 'DISABLED') {
- return;
- }
- levelKey = levelKey.toLowerCase();
-
- this[levelKey] = this.log.bind(this, level);
- this[levelKey].ln = this.logLn.bind(this, level);
- this[levelKey].ok = this.ok.bind(this, level);
- this[levelKey].fail = this.fail.bind(this, level);
- this[levelKey].promise = this.promise.bind(this, level);
- }, this);
-}
-
-/**
- Change minimum level
-
- @param {String} logLevel
-*/
-Logger.prototype.setLevel = function(logLevel) {
- if (is.string(logLevel)) {
- logLevel = logLevel.toUpperCase();
- logLevel = LEVELS.get(logLevel);
- }
-
- this.logLevel = logLevel;
-};
-
-/**
- Return minimum logging level
-
- @return {Number}
-*/
-Logger.prototype.getLevel = function(logLevel) {
- return this.logLevel;
-};
-
-/**
- Print a simple string
-
- @param {String}
-*/
-Logger.prototype.write = function(msg) {
- msg = msg.toString();
- this.lastChar = msg[msg.length - 1];
- return this._write(msg);
-};
-
-/**
- Format a string using the first argument as a printf-like format.
-*/
-Logger.prototype.format = function() {
- return util.format.apply(util, arguments);
-};
-
-/**
- Print a line
-
- @param {String}
-*/
-Logger.prototype.writeLn = function(msg) {
- return this.write((msg || '')+'\n');
-};
-
-/**
- Log/Print a message if level is allowed
-
- @param {Number} level
-*/
-Logger.prototype.log = function(level) {
- if (level < this.logLevel) return;
-
- var levelKey = LEVELS.findKey(function(v) {
- return v === level;
- });
- var args = Array.prototype.slice.apply(arguments, [1]);
- var msg = this.format.apply(this, args);
-
- if (this.lastChar == '\n') {
- msg = COLORS.get(levelKey)(levelKey.toLowerCase()+':')+' '+msg;
- }
-
- return this.write(msg);
-};
-
-/**
- Log/Print a line if level is allowed
-*/
-Logger.prototype.logLn = function() {
- if (this.lastChar != '\n') this.write('\n');
-
- var args = Array.prototype.slice.apply(arguments);
- args.push('\n');
- return this.log.apply(this, args);
-};
-
-/**
- Log a confirmation [OK]
-*/
-Logger.prototype.ok = function(level) {
- var args = Array.prototype.slice.apply(arguments, [1]);
- var msg = this.format.apply(this, args);
- if (arguments.length > 1) {
- this.logLn(level, color.green('>> ') + msg.trim().replace(/\n/g, color.green('\n>> ')));
- } else {
- this.log(level, color.green('OK'), '\n');
- }
-};
-
-/**
- Log a "FAIL"
-*/
-Logger.prototype.fail = function(level) {
- return this.log(level, color.red('ERROR') + '\n');
-};
-
-/**
- Log state of a promise
-
- @param {Number} level
- @param {Promise}
- @return {Promise}
-*/
-Logger.prototype.promise = function(level, p) {
- var that = this;
-
- return p.
- then(function(st) {
- that.ok(level);
- return st;
- }, function(err) {
- that.fail(level);
- throw err;
- });
-};
-
-Logger.LEVELS = LEVELS;
-
-module.exports = Logger;
diff --git a/lib/utils/mergeDefaults.js b/lib/utils/mergeDefaults.js
deleted file mode 100644
index 47a374b..0000000
--- a/lib/utils/mergeDefaults.js
+++ /dev/null
@@ -1,16 +0,0 @@
-var Immutable = require('immutable');
-
-/**
- * Merge
- * @param {Object|Map} obj
- * @param {Object|Map} src
- * @return {Object}
- */
-function mergeDefaults(obj, src) {
- var objValue = Immutable.fromJS(obj);
- var srcValue = Immutable.fromJS(src);
-
- return srcValue.mergeDeep(objValue).toJS();
-}
-
-module.exports = mergeDefaults;
diff --git a/lib/utils/path.js b/lib/utils/path.js
deleted file mode 100644
index 26b6005..0000000
--- a/lib/utils/path.js
+++ /dev/null
@@ -1,74 +0,0 @@
-var path = require('path');
-var error = require('./error');
-
-// Normalize a filename
-function normalizePath(filename) {
- return path.normalize(filename);
-}
-
-// Return true if file path is inside a folder
-function isInRoot(root, filename) {
- root = path.normalize(root);
- filename = path.normalize(filename);
-
- if (root === '.') {
- return true;
- }
- if (root[root.length - 1] != path.sep) {
- root = root + path.sep;
- }
-
- return (filename.substr(0, root.length) === root);
-}
-
-// Resolve paths in a specific folder
-// Throw error if file is outside this folder
-function resolveInRoot(root) {
- var input, result;
- var args = Array.prototype.slice.call(arguments, 1);
-
- input = args
- .reduce(function(current, p) {
- // Handle path relative to book root ("/README.md")
- if (p[0] == '/' || p[0] == '\\') return p.slice(1);
-
- return current? path.join(current, p) : path.normalize(p);
- }, '');
-
- result = path.resolve(root, input);
-
- if (!isInRoot(root, result)) {
- throw new error.FileOutOfScopeError({
- filename: result,
- root: root
- });
- }
-
- return result;
-}
-
-// Chnage extension of a file
-function setExtension(filename, ext) {
- return path.join(
- path.dirname(filename),
- path.basename(filename, path.extname(filename)) + ext
- );
-}
-
-/*
- Return true if a filename is relative.
-
- @param {String}
- @return {Boolean}
-*/
-function isPureRelative(filename) {
- return (filename.indexOf('./') === 0 || filename.indexOf('../') === 0);
-}
-
-module.exports = {
- isInRoot: isInRoot,
- resolveInRoot: resolveInRoot,
- normalize: normalizePath,
- setExtension: setExtension,
- isPureRelative: isPureRelative
-};
diff --git a/lib/utils/promise.js b/lib/utils/promise.js
deleted file mode 100644
index b5cca4b..0000000
--- a/lib/utils/promise.js
+++ /dev/null
@@ -1,148 +0,0 @@
-var Q = require('q');
-var Immutable = require('immutable');
-
-// Debugging for long stack traces
-if (process.env.DEBUG || process.env.CI) {
- Q.longStackSupport = true;
-}
-
-/**
- * Reduce an array to a promise
- *
- * @param {Array|List} arr
- * @param {Function(value, element, index)}
- * @return {Promise<Mixed>}
- */
-function reduce(arr, iter, base) {
- arr = Immutable.Iterable.isIterable(arr)? arr : Immutable.List(arr);
-
- return arr.reduce(function(prev, elem, key) {
- return prev
- .then(function(val) {
- return iter(val, elem, key);
- });
- }, Q(base));
-}
-
-/**
- * Iterate over an array using an async iter
- *
- * @param {Array|List} arr
- * @param {Function(value, element, index)}
- * @return {Promise}
- */
-function forEach(arr, iter) {
- return reduce(arr, function(val, el, key) {
- return iter(el, key);
- });
-}
-
-/**
- * Transform an array
- *
- * @param {Array|List} arr
- * @param {Function(value, element, index)}
- * @return {Promise}
- */
-function serie(arr, iter, base) {
- return reduce(arr, function(before, item, key) {
- return Q(iter(item, key))
- .then(function(r) {
- before.push(r);
- return before;
- });
- }, []);
-}
-
-/**
- * Iter over an array and return first result (not null)
- *
- * @param {Array|List} arr
- * @param {Function(element, index)}
- * @return {Promise<Mixed>}
- */
-function some(arr, iter) {
- arr = Immutable.List(arr);
-
- return arr.reduce(function(prev, elem, i) {
- return prev.then(function(val) {
- if (val) return val;
-
- return iter(elem, i);
- });
- }, Q());
-}
-
-/**
- * Map an array using an async (promised) iterator
- *
- * @param {Array|List} arr
- * @param {Function(element, index)}
- * @return {Promise<List>}
- */
-function mapAsList(arr, iter) {
- return reduce(arr, function(prev, entry, i) {
- return Q(iter(entry, i))
- .then(function(out) {
- prev.push(out);
- return prev;
- });
- }, []);
-}
-
-/**
- * Map an array or map
- *
- * @param {Array|List|Map|OrderedMap} arr
- * @param {Function(element, key)}
- * @return {Promise<List|Map|OrderedMap>}
- */
-function map(arr, iter) {
- if (Immutable.Map.isMap(arr)) {
- var type = 'Map';
- if (Immutable.OrderedMap.isOrderedMap(arr)) {
- type = 'OrderedMap';
- }
-
- return mapAsList(arr, function(value, key) {
- return Q(iter(value, key))
- .then(function(result) {
- return [key, result];
- });
- })
- .then(function(result) {
- return Immutable[type](result);
- });
- } else {
- return mapAsList(arr, iter)
- .then(function(result) {
- return Immutable.List(result);
- });
- }
-}
-
-
-/**
- * Wrap a function in a promise
- *
- * @param {Function} func
- * @return {Funciton}
- */
-function wrap(func) {
- return function() {
- var args = Array.prototype.slice.call(arguments, 0);
-
- return Q()
- .then(function() {
- return func.apply(null, args);
- });
- };
-}
-
-module.exports = Q;
-module.exports.forEach = forEach;
-module.exports.reduce = reduce;
-module.exports.map = map;
-module.exports.serie = serie;
-module.exports.some = some;
-module.exports.wrapfn = wrap;
diff --git a/lib/utils/reducedObject.js b/lib/utils/reducedObject.js
deleted file mode 100644
index 7bcfd5b..0000000
--- a/lib/utils/reducedObject.js
+++ /dev/null
@@ -1,33 +0,0 @@
-var Immutable = require('immutable');
-
-/**
- * Reduce the difference between a map and its default version
- * @param {Map} defaultVersion
- * @param {Map} currentVersion
- * @return {Map} The properties of currentVersion that differs from defaultVersion
- */
-function reducedObject(defaultVersion, currentVersion) {
- if(defaultVersion === undefined) {
- return currentVersion;
- }
-
- return currentVersion.reduce(function(result, value, key) {
- var defaultValue = defaultVersion.get(key);
-
- if (Immutable.Map.isMap(value)) {
- var diffs = reducedObject(defaultValue, value);
-
- if (diffs.size > 0) {
- return result.set(key, diffs);
- }
- }
-
- if (Immutable.is(defaultValue, value)) {
- return result;
- }
-
- return result.set(key, value);
- }, Immutable.Map());
-}
-
-module.exports = reducedObject;
diff --git a/lib/utils/timing.js b/lib/utils/timing.js
deleted file mode 100644
index e6b0323..0000000
--- a/lib/utils/timing.js
+++ /dev/null
@@ -1,97 +0,0 @@
-var Immutable = require('immutable');
-var is = require('is');
-
-var timers = {};
-var startDate = Date.now();
-
-/**
- Mesure an operation
-
- @parqm {String} type
- @param {Promise} p
- @return {Promise}
-*/
-function measure(type, p) {
- timers[type] = timers[type] || {
- type: type,
- count: 0,
- total: 0,
- min: undefined,
- max: 0
- };
-
- var start = Date.now();
-
- return p
- .fin(function() {
- var end = Date.now();
- var duration = (end - start);
-
- timers[type].count ++;
- timers[type].total += duration;
-
- if (is.undefined(timers[type].min)) {
- timers[type].min = duration;
- } else {
- timers[type].min = Math.min(timers[type].min, duration);
- }
-
- timers[type].max = Math.max(timers[type].max, duration);
- });
-}
-
-/**
- Return a milliseconds number as a second string
-
- @param {Number} ms
- @return {String}
-*/
-function time(ms) {
- if (ms < 1000) {
- return (ms.toFixed(0)) + 'ms';
- }
-
- return (ms/1000).toFixed(2) + 's';
-}
-
-/**
- Dump all timers to a logger
-
- @param {Logger} logger
-*/
-function dump(logger) {
- var prefix = ' > ';
- var measured = 0;
- var totalDuration = Date.now() - startDate;
-
- // Enable debug logging
- var logLevel = logger.getLevel();
- logger.setLevel('debug');
-
- Immutable.Map(timers)
- .valueSeq()
- .sortBy(function(timer) {
- measured += timer.total;
- return timer.total;
- })
- .forEach(function(timer) {
- var percent = (timer.total * 100) / totalDuration;
-
-
- logger.debug.ln((percent.toFixed(1)) + '% of time spent in "' + timer.type + '" (' + timer.count + ' times) :');
- logger.debug.ln(prefix + 'Total: ' + time(timer.total)+ ' | Average: ' + time(timer.total / timer.count));
- logger.debug.ln(prefix + 'Min: ' + time(timer.min) + ' | Max: ' + time(timer.max));
- logger.debug.ln('---------------------------');
- });
-
-
- logger.debug.ln(time(totalDuration - measured) + ' spent in non-mesured sections');
-
- // Rollback to previous level
- logger.setLevel(logLevel);
-}
-
-module.exports = {
- measure: measure,
- dump: dump
-};