diff options
author | Samy Pessé <samypesse@gmail.com> | 2016-04-25 14:44:49 +0200 |
---|---|---|
committer | Samy Pessé <samypesse@gmail.com> | 2016-04-25 14:44:49 +0200 |
commit | 4552ccd7d76a1bf958481e24a695dd3b68e6c232 (patch) | |
tree | d96ca1329846062007700b6a28d696f0f10f9e18 /lib/templating | |
parent | 525bcd8295f72ffa09d485f86c7adea2187cde55 (diff) | |
download | gitbook-4552ccd7d76a1bf958481e24a695dd3b68e6c232.zip gitbook-4552ccd7d76a1bf958481e24a695dd3b68e6c232.tar.gz gitbook-4552ccd7d76a1bf958481e24a695dd3b68e6c232.tar.bz2 |
Add loader for themes
Diffstat (limited to 'lib/templating')
-rw-r--r-- | lib/templating/index.js | 3 | ||||
-rw-r--r-- | lib/templating/themesLoader.js | 117 |
2 files changed, 119 insertions, 1 deletions
diff --git a/lib/templating/index.js b/lib/templating/index.js index 4cdf6ef..a33965d 100644 --- a/lib/templating/index.js +++ b/lib/templating/index.js @@ -4,5 +4,6 @@ module.exports = { renderFile: require('./renderFile'), postRender: require('./postRender'), - ConrefsLoader: require('./conrefsLoader') + ConrefsLoader: require('./conrefsLoader'), + ThemesLoader: require('./themesLoader') }; diff --git a/lib/templating/themesLoader.js b/lib/templating/themesLoader.js new file mode 100644 index 0000000..2b436a4 --- /dev/null +++ b/lib/templating/themesLoader.js @@ -0,0 +1,117 @@ +var Immutable = require('immutable'); +var nunjucks = require('nunjucks'); +var fs = require('fs'); +var path = require('path'); + +var PathUtils = require('../utils/path'); + +/** + +*/ +var ThemesLoader = nunjucks.Loader.extend({ + init: function(searchPaths) { + this.searchPaths = Immutable.List(searchPaths) + .map(path.normalize); + }, + + /* + Read source of a resolved filepath + @param {String} + @return {Object} + */ + getSource: function(fullpath) { + if (!fullpath) return null; + + fullpath = this.resolve(null, fullpath); + var templateName = this.getTemplateName(fullpath); + + if(!fullpath) { + return null; + } + + var src = fs.readFileSync(fullpath, 'utf-8'); + + src = '{% do %}var template = template || {}; template.stack = template.stack || []; template.stack.push(template.self); template.self = ' + JSON.stringify(templateName) + '{% enddo %}\n' + + src + + '\n{% do %}template.self = template.stack.pop();{% enddo %}'; + + return { + src: src, + path: fullpath, + noCache: true + }; + }, + + /* + Nunjucks calls "isRelative" to determine when to call "resolve". + We handle absolute paths ourselves in ".resolve" so we always return true + */ + isRelative: function() { + return true; + }, + + /* + Get original search path containing a template + @param {String} filepath + @return {String} searchPath + */ + getSearchPath: function(filepath) { + return this.searchPaths + .sortBy(function(s) { + return -s.length; + }) + .find(function(basePath) { + return (filepath && filepath.indexOf(basePath) === 0); + }); + }, + + /* + Get template name from a filepath + @param {String} filepath + @return {String} name + */ + getTemplateName: function(filepath) { + var originalSearchPath = this.getSearchPath(filepath); + return originalSearchPath? path.relative(originalSearchPath, filepath) : null; + }, + + /* + Resolve a template from a current template + @param {String|null} from + @param {String} to + @return {String|null} + */ + resolve: function(from, to) { + var searchPaths = this.searchPaths; + + // Relative template like "./test.html" + if (PathUtils.isPureRelative(to) && from) { + return path.resolve(path.dirname(from), to); + } + + // Determine in which search folder we currently are + var originalSearchPath = this.getSearchPath(from); + var originalFilename = this.getTemplateName(from); + + // If we are including same file from a different search path + // Slice the search paths to avoid including from previous ones + if (originalFilename == to) { + var currentIndex = searchPaths.indexOf(originalSearchPath); + searchPaths = searchPaths.slice(currentIndex + 1); + } + + // Absolute template to resolve in root folder + var resultFolder = searchPaths.find(function(basePath) { + var p = path.resolve(basePath, to); + + return ( + p.indexOf(basePath) === 0 + && fs.existsSync(p) + ); + }); + if (!resultFolder) return null; + return path.resolve(resultFolder, to); + } +}); + +module.exports = ThemesLoader; |