summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorJohan Preynat <johan.preynat@gmail.com>2016-10-09 00:58:30 +0200
committerJohan Preynat <johan.preynat@gmail.com>2016-10-09 00:58:30 +0200
commit5a57a2c62ad67210143bfe5dd96dd1605b3724f6 (patch)
tree94cef22779ea438a44eaf3fa3b201456652d7005 /packages
parent4cfffb26f265ce1af71e1f34dc0a9468ad0caaf1 (diff)
parent2d429b731b7ebbf6480f62efa379dad48ee7bdee (diff)
downloadgitbook-5a57a2c62ad67210143bfe5dd96dd1605b3724f6.zip
gitbook-5a57a2c62ad67210143bfe5dd96dd1605b3724f6.tar.gz
gitbook-5a57a2c62ad67210143bfe5dd96dd1605b3724f6.tar.bz2
Merge remote-tracking branch 'origin/dream' into dream
# Conflicts: # packages/gitbook-plugin-headings/package.json
Diffstat (limited to 'packages')
-rw-r--r--packages/gitbook-core/package.json96
-rw-r--r--packages/gitbook-core/src/lib/bootstrap.js7
-rw-r--r--packages/gitbook-core/src/lib/renderWithContext.js12
-rw-r--r--packages/gitbook-plugin-headings/package.json6
-rw-r--r--packages/gitbook-plugin-highlight/package.json56
-rw-r--r--packages/gitbook-plugin-hints/package.json56
-rw-r--r--packages/gitbook-plugin-lunr/package.json74
-rw-r--r--packages/gitbook-plugin-search/package.json56
-rw-r--r--packages/gitbook-plugin-sharing/package.json54
-rw-r--r--packages/gitbook-plugin-theme-default/less/Body.less5
-rw-r--r--packages/gitbook-plugin-theme-default/less/main.less1
-rw-r--r--packages/gitbook-plugin-theme-default/package.json154
-rw-r--r--packages/gitbook-plugin-theme-default/src/index.js2
-rw-r--r--packages/gitbook-plugin/package.json76
-rw-r--r--packages/gitbook/package.json218
-rw-r--r--packages/gitbook/src/browser/loadPlugins.js10
-rw-r--r--packages/gitbook/src/browser/render.js30
-rw-r--r--packages/gitbook/src/json/encodeState.js7
-rw-r--r--packages/gitbook/src/models/__tests__/page.js5
-rw-r--r--packages/gitbook/src/models/__tests__/templateBlock.js98
-rw-r--r--packages/gitbook/src/models/__tests__/uriIndex.js14
-rw-r--r--packages/gitbook/src/models/ignore.js65
-rw-r--r--packages/gitbook/src/models/templateBlock.js410
-rw-r--r--packages/gitbook/src/models/templateEngine.js244
-rw-r--r--packages/gitbook/src/models/templateOutput.js42
-rw-r--r--packages/gitbook/src/output/__tests__/generateMock.js2
-rw-r--r--packages/gitbook/src/output/ebook/getPDFTemplate.js39
-rw-r--r--packages/gitbook/src/output/ebook/onFinish.js50
-rw-r--r--packages/gitbook/src/output/ebook/onPage.js11
-rw-r--r--packages/gitbook/src/output/ebook/options.js11
-rw-r--r--packages/gitbook/src/output/generateBook.js6
-rw-r--r--packages/gitbook/src/output/generatePage.js23
-rw-r--r--packages/gitbook/src/output/website/onPage.js2
-rw-r--r--packages/gitbook/src/parse/__tests__/parseURIIndexFromPages.js15
-rw-r--r--packages/gitbook/src/templating/__tests__/conrefsLoader.js53
-rw-r--r--packages/gitbook/src/templating/__tests__/postRender.js51
-rw-r--r--packages/gitbook/src/templating/index.js11
-rw-r--r--packages/gitbook/src/templating/listShortcuts.js6
-rw-r--r--packages/gitbook/src/templating/postRender.js53
-rw-r--r--packages/gitbook/src/templating/render.js6
-rw-r--r--packages/gitbook/src/templating/themesLoader.js115
41 files changed, 992 insertions, 1260 deletions
diff --git a/packages/gitbook-core/package.json b/packages/gitbook-core/package.json
index 4e3974e..0c444b7 100644
--- a/packages/gitbook-core/package.json
+++ b/packages/gitbook-core/package.json
@@ -1,49 +1,49 @@
{
- "name": "gitbook-core",
- "version": "0.0.0",
- "description": "Core for GitBook plugins API",
- "main": "./lib/index.js",
- "dependencies": {
- "bluebird": "^3.4.6",
- "classnames": "^2.2.5",
- "entities": "^1.1.1",
- "history": "^4.3.0",
- "html-tags": "^1.1.1",
- "immutable": "^3.8.1",
- "react": "^15.3.1",
- "react-dom": "^15.3.1",
- "react-helmet": "^3.1.0",
- "react-immutable-proptypes": "^2.1.0",
- "react-intl": "^2.1.5",
- "react-redux": "^4.4.5",
- "react-safe-html": "^0.3.0",
- "redux": "^3.5.2",
- "redux-thunk": "^2.1.0",
- "reflexbox": "^2.2.2",
- "whatwg-fetch": "^1.0.0"
- },
- "devDependencies": {
- "babel-cli": "^6.14.0",
- "babel-preset-es2015": "^6.14.0",
- "babel-preset-react": "^6.11.1",
- "babel-preset-stage-2": "^6.13.0",
- "browserify": "^13.1.0",
- "envify": "^3.4.1",
- "uglify-js": "^2.7.3"
- },
- "scripts": {
- "dist-lib": "rm -rf lib/ && babel -d lib/ src/",
- "dist-standalone": "mkdir -p dist && browserify -r ./lib/index.js:gitbook-core -r react -r react-dom ./lib/index.js | uglifyjs -c > ./dist/gitbook.core.min.js",
- "dist": "npm run dist-lib && npm run dist-standalone",
- "prepublish": "npm run dist"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/GitbookIO/gitbook.git"
- },
- "author": "GitBook Inc. <contact@gitbook.com>",
- "license": "Apache-2.0",
- "bugs": {
- "url": "https://github.com/GitbookIO/gitbook/issues"
- }
-}
+ "name": "gitbook-core",
+ "version": "4.0.0",
+ "description": "Core for GitBook plugins API",
+ "main": "./lib/index.js",
+ "dependencies": {
+ "bluebird": "^3.4.6",
+ "classnames": "^2.2.5",
+ "entities": "^1.1.1",
+ "history": "^4.3.0",
+ "html-tags": "^1.1.1",
+ "immutable": "^3.8.1",
+ "react": "^15.3.1",
+ "react-dom": "^15.3.1",
+ "react-helmet": "^3.1.0",
+ "react-immutable-proptypes": "^2.1.0",
+ "react-intl": "^2.1.5",
+ "react-redux": "^4.4.5",
+ "react-safe-html": "^0.3.0",
+ "redux": "^3.5.2",
+ "redux-thunk": "^2.1.0",
+ "reflexbox": "^2.2.2",
+ "whatwg-fetch": "^1.0.0"
+ },
+ "devDependencies": {
+ "babel-cli": "^6.14.0",
+ "babel-preset-es2015": "^6.14.0",
+ "babel-preset-react": "^6.11.1",
+ "babel-preset-stage-2": "^6.13.0",
+ "browserify": "^13.1.0",
+ "envify": "^3.4.1",
+ "uglify-js": "^2.7.3"
+ },
+ "scripts": {
+ "dist-lib": "rm -rf lib/ && babel -d lib/ src/",
+ "dist-standalone": "mkdir -p dist && browserify -r ./lib/index.js:gitbook-core -r react -r react-dom ./lib/index.js | uglifyjs -c > ./dist/gitbook.core.min.js",
+ "dist": "npm run dist-lib && npm run dist-standalone",
+ "prepublish": "npm run dist"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/GitbookIO/gitbook.git"
+ },
+ "author": "GitBook Inc. <contact@gitbook.com>",
+ "license": "Apache-2.0",
+ "bugs": {
+ "url": "https://github.com/GitbookIO/gitbook/issues"
+ }
+} \ No newline at end of file
diff --git a/packages/gitbook-core/src/lib/bootstrap.js b/packages/gitbook-core/src/lib/bootstrap.js
index f5183d1..f3c99b7 100644
--- a/packages/gitbook-core/src/lib/bootstrap.js
+++ b/packages/gitbook-core/src/lib/bootstrap.js
@@ -5,9 +5,10 @@ const createContext = require('./createContext');
const renderWithContext = require('./renderWithContext');
/**
- * Bootstrap GitBook on the browser (this function should not be called on the server side)
+ * Bootstrap GitBook on the browser (this function should not be called on the server side).
+ * @param {Object} matching
*/
-function bootstrap() {
+function bootstrap(matching) {
const initialState = getPayload(window.document);
const plugins = window.gitbookPlugins;
@@ -19,7 +20,7 @@ function bootstrap() {
window.gitbookContext = context;
// Render with the store
- const el = renderWithContext(context);
+ const el = renderWithContext(context, matching);
ReactDOM.render(el, mountNode);
}
diff --git a/packages/gitbook-core/src/lib/renderWithContext.js b/packages/gitbook-core/src/lib/renderWithContext.js
index 44f8ba4..f9a093c 100644
--- a/packages/gitbook-core/src/lib/renderWithContext.js
+++ b/packages/gitbook-core/src/lib/renderWithContext.js
@@ -9,7 +9,8 @@ const contextShape = require('../shapes/context');
const GitBookApplication = React.createClass({
propTypes: {
- context: contextShape
+ context: contextShape,
+ matching: React.PropTypes.object
},
componentDidMount() {
@@ -23,13 +24,13 @@ const GitBookApplication = React.createClass({
},
render() {
- const { context } = this.props;
+ const { context, matching } = this.props;
return (
<ContextProvider context={context}>
<PJAXWrapper>
<I18nProvider>
- <InjectedComponent matching={{ role: 'Body' }} />
+ <InjectedComponent matching={matching} />
</I18nProvider>
</PJAXWrapper>
</ContextProvider>
@@ -42,11 +43,12 @@ const GitBookApplication = React.createClass({
* Render the application for a GitBook context.
*
* @param {GitBookContext} context
+ * @param {Object} matching
* @return {React.Element} element
*/
-function renderWithContext(context) {
+function renderWithContext(context, matching) {
return (
- <GitBookApplication context={context} />
+ <GitBookApplication context={context} matching={matching} />
);
}
diff --git a/packages/gitbook-plugin-headings/package.json b/packages/gitbook-plugin-headings/package.json
index dc2fbcd..3eb8b76 100644
--- a/packages/gitbook-plugin-headings/package.json
+++ b/packages/gitbook-plugin-headings/package.json
@@ -3,13 +3,13 @@
"description": "Automatically add anchors to headings",
"main": "index.js",
"browser": "./_assets/plugin.js",
- "version": "1.0.0",
+ "version": "4.0.0",
"dependencies": {
"classnames": "^2.2.5",
- "gitbook-core": "^0.0.0"
+ "gitbook-core": "^4.0.0"
},
"devDependencies": {
- "gitbook-plugin": "*"
+ "gitbook-plugin": "4.0.0"
},
"engines": {
"gitbook": ">=3.0.0"
diff --git a/packages/gitbook-plugin-highlight/package.json b/packages/gitbook-plugin-highlight/package.json
index a174e6c..03d2af7 100644
--- a/packages/gitbook-plugin-highlight/package.json
+++ b/packages/gitbook-plugin-highlight/package.json
@@ -1,29 +1,29 @@
{
- "name": "gitbook-plugin-highlight",
- "description": "Syntax highlighter for Gitbook",
- "main": "index.js",
- "browser": "./_assets/plugin.js",
- "version": "2.0.2",
- "dependencies": {
- "gitbook-core": "^0.0.0",
- "highlight.js": "9.7.0"
- },
- "devDependencies": {
- "gitbook-plugin": "*"
- },
- "engines": {
- "gitbook": ">=3.0.0"
- },
- "scripts": {
- "build-js": "gitbook-plugin build ./src/index.js ./_assets/plugin.js",
- "prepublish": "npm run build-js"
- },
- "homepage": "https://github.com/GitbookIO/gitbook",
- "repository": {
- "type": "git",
- "url": "https://github.com/GitbookIO/gitbook.git"
- },
- "bugs": {
- "url": "https://github.com/GitbookIO/gitbook/issues"
- }
-}
+ "name": "gitbook-plugin-highlight",
+ "description": "Syntax highlighter for Gitbook",
+ "main": "index.js",
+ "browser": "./_assets/plugin.js",
+ "version": "4.0.0",
+ "dependencies": {
+ "gitbook-core": "4.0.0",
+ "highlight.js": "9.7.0"
+ },
+ "devDependencies": {
+ "gitbook-plugin": "4.0.0"
+ },
+ "engines": {
+ "gitbook": ">=3.0.0"
+ },
+ "scripts": {
+ "build-js": "gitbook-plugin build ./src/index.js ./_assets/plugin.js",
+ "prepublish": "npm run build-js"
+ },
+ "homepage": "https://github.com/GitbookIO/gitbook",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/GitbookIO/gitbook.git"
+ },
+ "bugs": {
+ "url": "https://github.com/GitbookIO/gitbook/issues"
+ }
+} \ No newline at end of file
diff --git a/packages/gitbook-plugin-hints/package.json b/packages/gitbook-plugin-hints/package.json
index 1635d36..66dedd0 100644
--- a/packages/gitbook-plugin-hints/package.json
+++ b/packages/gitbook-plugin-hints/package.json
@@ -1,29 +1,29 @@
{
- "name": "gitbook-plugin-hints",
- "description": "Defines four types of styled hint blocks: info, danger, tip, working.",
- "main": "index.js",
- "browser": "./_assets/plugin.js",
- "version": "2.0.0",
- "dependencies": {
- "classnames": "^2.2.5",
- "gitbook-core": "^0.0.0"
- },
- "devDependencies": {
- "gitbook-plugin": "*"
- },
- "engines": {
- "gitbook": ">=4.0.0"
- },
- "scripts": {
- "build-js": "gitbook-plugin build ./src/index.js ./_assets/plugin.js",
- "prepublish": "npm run build-js"
- },
- "homepage": "https://github.com/GitBookIO/gitbook",
- "repository": {
- "type": "git",
- "url": "https://github.com/GitBookIO/gitbook.git"
- },
- "bugs": {
- "url": "https://github.com/GitBookIO/gitbook/issues"
- }
-}
+ "name": "gitbook-plugin-hints",
+ "description": "Defines four types of styled hint blocks: info, danger, tip, working.",
+ "main": "index.js",
+ "browser": "./_assets/plugin.js",
+ "version": "4.0.0",
+ "dependencies": {
+ "classnames": "^2.2.5",
+ "gitbook-core": "4.0.0"
+ },
+ "devDependencies": {
+ "gitbook-plugin": "4.0.0"
+ },
+ "engines": {
+ "gitbook": ">=4.0.0"
+ },
+ "scripts": {
+ "build-js": "gitbook-plugin build ./src/index.js ./_assets/plugin.js",
+ "prepublish": "npm run build-js"
+ },
+ "homepage": "https://github.com/GitBookIO/gitbook",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/GitBookIO/gitbook.git"
+ },
+ "bugs": {
+ "url": "https://github.com/GitBookIO/gitbook/issues"
+ }
+} \ No newline at end of file
diff --git a/packages/gitbook-plugin-lunr/package.json b/packages/gitbook-plugin-lunr/package.json
index a5e5d61..7093e7f 100644
--- a/packages/gitbook-plugin-lunr/package.json
+++ b/packages/gitbook-plugin-lunr/package.json
@@ -1,44 +1,44 @@
{
- "name": "gitbook-plugin-lunr",
- "description": "Static and local index for search in GitBook",
- "main": "index.js",
- "browser": "./_assets/theme.js",
- "version": "1.2.0",
- "dependencies": {
- "gitbook-core": "^0.0.0",
- "html-entities": "1.2.0",
- "lunr": "0.5.12"
- },
- "devDependencies": {
- "gitbook-plugin": "*"
- },
- "engines": {
- "gitbook": ">=3.0.0"
- },
- "gitbook": {
- "properties": {
- "maxIndexSize": {
+ "name": "gitbook-plugin-lunr",
+ "description": "Static and local index for search in GitBook",
+ "main": "index.js",
+ "browser": "./_assets/theme.js",
+ "version": "4.0.0",
+ "dependencies": {
+ "gitbook-core": "4.0.0",
+ "html-entities": "1.2.0",
+ "lunr": "0.5.12"
+ },
+ "devDependencies": {
+ "gitbook-plugin": "4.0.0"
+ },
+ "engines": {
+ "gitbook": ">=3.0.0"
+ },
+ "gitbook": {
+ "properties": {
+ "maxIndexSize": {
"type": "number",
"title": "Limit size for the index",
"default": 1000000
- },
- "ignoreSpecialCharacters": {
+ },
+ "ignoreSpecialCharacters": {
"type": "boolean",
"title": "Ignore special characters in words",
"default": false
- }
- }
- },
- "scripts": {
- "build-js": "gitbook-plugin build ./src/index.js ./_assets/theme.js",
- "prepublish": "npm run build-js"
- },
- "homepage": "https://github.com/GitBookIO/gitbook",
- "repository": {
- "type": "git",
- "url": "https://github.com/GitBookIO/gitbook.git"
- },
- "bugs": {
- "url": "https://github.com/GitBookIO/gitbook/issues"
- }
-}
+ }
+ }
+ },
+ "scripts": {
+ "build-js": "gitbook-plugin build ./src/index.js ./_assets/theme.js",
+ "prepublish": "npm run build-js"
+ },
+ "homepage": "https://github.com/GitBookIO/gitbook",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/GitBookIO/gitbook.git"
+ },
+ "bugs": {
+ "url": "https://github.com/GitBookIO/gitbook/issues"
+ }
+} \ No newline at end of file
diff --git a/packages/gitbook-plugin-search/package.json b/packages/gitbook-plugin-search/package.json
index d6741c9..2a5c610 100644
--- a/packages/gitbook-plugin-search/package.json
+++ b/packages/gitbook-plugin-search/package.json
@@ -1,29 +1,29 @@
{
- "name": "gitbook-plugin-search",
- "description": "Search integration in GitBook",
- "main": "index.js",
- "browser": "./_assets/theme.js",
- "version": "2.2.1",
- "dependencies": {
- "gitbook-core": "^0.0.0"
- },
- "devDependencies": {
- "gitbook-plugin": "*"
- },
- "engines": {
- "gitbook": ">=3.0.0"
- },
- "scripts": {
- "build-js": "gitbook-plugin build ./src/index.js ./_assets/theme.js",
- "prepublish": "npm run build-js"
- },
- "homepage": "https://github.com/GitbookIO/gitbook",
- "repository": {
- "type": "git",
- "url": "https://github.com/GitbookIO/gitbook.git"
- },
- "license": "Apache-2.0",
- "bugs": {
- "url": "https://github.com/GitbookIO/gitbook/issues"
- }
-}
+ "name": "gitbook-plugin-search",
+ "description": "Search integration in GitBook",
+ "main": "index.js",
+ "browser": "./_assets/theme.js",
+ "version": "4.0.0",
+ "dependencies": {
+ "gitbook-core": "4.0.0"
+ },
+ "devDependencies": {
+ "gitbook-plugin": "4.0.0"
+ },
+ "engines": {
+ "gitbook": ">=3.0.0"
+ },
+ "scripts": {
+ "build-js": "gitbook-plugin build ./src/index.js ./_assets/theme.js",
+ "prepublish": "npm run build-js"
+ },
+ "homepage": "https://github.com/GitbookIO/gitbook",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/GitbookIO/gitbook.git"
+ },
+ "license": "Apache-2.0",
+ "bugs": {
+ "url": "https://github.com/GitbookIO/gitbook/issues"
+ }
+} \ No newline at end of file
diff --git a/packages/gitbook-plugin-sharing/package.json b/packages/gitbook-plugin-sharing/package.json
index 21fc038..9586ae3 100644
--- a/packages/gitbook-plugin-sharing/package.json
+++ b/packages/gitbook-plugin-sharing/package.json
@@ -1,28 +1,28 @@
{
- "name": "gitbook-plugin-sharing",
- "description": "Sharing buttons in the toolbar",
- "main": "index.js",
- "browser": "./_assets/plugin.js",
- "version": "4.0.0",
- "dependencies": {
- "gitbook-core": "^0.0.0"
- },
- "devDependencies": {
- "gitbook-plugin": "*"
- },
- "engines": {
- "gitbook": ">=3.0.0"
- },
- "scripts": {
- "build-js": "gitbook-plugin build ./src/index.js ./_assets/plugin.js",
- "prepublish": "npm run build-js"
- },
- "homepage": "https://github.com/GitbookIO/gitbook",
- "repository": {
- "type": "git",
- "url": "https://github.com/GitbookIO/gitbook.git"
- },
- "bugs": {
- "url": "https://github.com/GitbookIO/gitbook/issues"
- }
-}
+ "name": "gitbook-plugin-sharing",
+ "description": "Sharing buttons in the toolbar",
+ "main": "index.js",
+ "browser": "./_assets/plugin.js",
+ "version": "4.0.0",
+ "dependencies": {
+ "gitbook-core": "4.0.0"
+ },
+ "devDependencies": {
+ "gitbook-plugin": "4.0.0"
+ },
+ "engines": {
+ "gitbook": ">=3.0.0"
+ },
+ "scripts": {
+ "build-js": "gitbook-plugin build ./src/index.js ./_assets/plugin.js",
+ "prepublish": "npm run build-js"
+ },
+ "homepage": "https://github.com/GitbookIO/gitbook",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/GitbookIO/gitbook.git"
+ },
+ "bugs": {
+ "url": "https://github.com/GitbookIO/gitbook/issues"
+ }
+} \ No newline at end of file
diff --git a/packages/gitbook-plugin-theme-default/less/Body.less b/packages/gitbook-plugin-theme-default/less/Body.less
new file mode 100644
index 0000000..7524a24
--- /dev/null
+++ b/packages/gitbook-plugin-theme-default/less/Body.less
@@ -0,0 +1,5 @@
+.Body {
+ overflow: auto;
+ width: 100%;
+ height: 100%;
+}
diff --git a/packages/gitbook-plugin-theme-default/less/main.less b/packages/gitbook-plugin-theme-default/less/main.less
index 9858a2f..cb5d07d 100644
--- a/packages/gitbook-plugin-theme-default/less/main.less
+++ b/packages/gitbook-plugin-theme-default/less/main.less
@@ -12,6 +12,7 @@
@import "Page.less";
@import "Toolbar.less";
@import "Search.less";
+@import "Body.less";
* {
.box-sizing(border-box);
diff --git a/packages/gitbook-plugin-theme-default/package.json b/packages/gitbook-plugin-theme-default/package.json
index d26b46a..599f64c 100644
--- a/packages/gitbook-plugin-theme-default/package.json
+++ b/packages/gitbook-plugin-theme-default/package.json
@@ -1,79 +1,79 @@
{
- "name": "gitbook-plugin-theme-default",
- "description": "Default theme for GitBook",
- "main": "./index.js",
- "browser": "./_assets/theme.js",
- "version": "1.0.5",
- "engines": {
- "gitbook": ">=3.0.0"
- },
- "dependencies": {
- "gitbook-core": "^0.0.0"
- },
- "devDependencies": {
- "classnames": "^2.2.5",
- "font-awesome": "^4.6.3",
- "gitbook-markdown-css": "^1.0.1",
- "gitbook-plugin": "*",
- "less": "^2.7.1",
- "less-plugin-clean-css": "^1.5.1",
- "preboot": "git+https://github.com/mdo/preboot.git#4aab4edd85f076d50609cbe28e4fe66cc0771701"
- },
- "scripts": {
- "prepublish": "./prepublish.sh"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/GitbookIO/gitbook.git"
- },
- "author": "GitBook Inc. <contact@gitbook.com>",
- "license": "Apache-2.0",
- "bugs": {
- "url": "https://github.com/GitbookIO/gitbook/issues"
- },
- "contributors": [
- {
- "name": "Samy Pessé",
- "email": "samy@gitbook.com"
- }
- ],
- "gitbook": {
- "properties": {
- "styles": {
- "type": "object",
- "title": "Custom Stylesheets",
- "properties": {
- "website": {
- "title": "Stylesheet for website output",
- "default": "styles/website.css"
- },
- "pdf": {
- "title": "Stylesheet for PDF output",
- "default": "styles/pdf.css"
- },
- "epub": {
- "title": "Stylesheet for ePub output",
- "default": "styles/epub.css"
- },
- "mobi": {
- "title": "Stylesheet for Mobi output",
- "default": "styles/mobi.css"
- },
- "ebook": {
- "title": "Stylesheet for ebook outputs (PDF, ePub, Mobi)",
- "default": "styles/ebook.css"
- },
- "print": {
- "title": "Stylesheet to replace default ebook css",
- "default": "styles/print.css"
- }
- }
- },
- "showLevel": {
- "type": "boolean",
- "title": "Show level indicator in TOC",
- "default": false
+ "name": "gitbook-plugin-theme-default",
+ "description": "Default theme for GitBook",
+ "main": "./index.js",
+ "browser": "./_assets/theme.js",
+ "version": "4.0.0",
+ "engines": {
+ "gitbook": ">=3.0.0"
+ },
+ "dependencies": {
+ "gitbook-core": "4.0.0"
+ },
+ "devDependencies": {
+ "classnames": "^2.2.5",
+ "font-awesome": "^4.6.3",
+ "gitbook-markdown-css": "^1.0.1",
+ "gitbook-plugin": "4.0.0",
+ "less": "^2.7.1",
+ "less-plugin-clean-css": "^1.5.1",
+ "preboot": "git+https://github.com/mdo/preboot.git#4aab4edd85f076d50609cbe28e4fe66cc0771701"
+ },
+ "scripts": {
+ "prepublish": "./prepublish.sh"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/GitbookIO/gitbook.git"
+ },
+ "author": "GitBook Inc. <contact@gitbook.com>",
+ "license": "Apache-2.0",
+ "bugs": {
+ "url": "https://github.com/GitbookIO/gitbook/issues"
+ },
+ "contributors": [
+ {
+ "name": "Samy Pessé",
+ "email": "samy@gitbook.com"
}
- }
- }
-}
+ ],
+ "gitbook": {
+ "properties": {
+ "styles": {
+ "type": "object",
+ "title": "Custom Stylesheets",
+ "properties": {
+ "website": {
+ "title": "Stylesheet for website output",
+ "default": "styles/website.css"
+ },
+ "pdf": {
+ "title": "Stylesheet for PDF output",
+ "default": "styles/pdf.css"
+ },
+ "epub": {
+ "title": "Stylesheet for ePub output",
+ "default": "styles/epub.css"
+ },
+ "mobi": {
+ "title": "Stylesheet for Mobi output",
+ "default": "styles/mobi.css"
+ },
+ "ebook": {
+ "title": "Stylesheet for ebook outputs (PDF, ePub, Mobi)",
+ "default": "styles/ebook.css"
+ },
+ "print": {
+ "title": "Stylesheet to replace default ebook css",
+ "default": "styles/print.css"
+ }
+ }
+ },
+ "showLevel": {
+ "type": "boolean",
+ "title": "Show level indicator in TOC",
+ "default": false
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/gitbook-plugin-theme-default/src/index.js b/packages/gitbook-plugin-theme-default/src/index.js
index c391908..ad96175 100644
--- a/packages/gitbook-plugin-theme-default/src/index.js
+++ b/packages/gitbook-plugin-theme-default/src/index.js
@@ -7,7 +7,7 @@ const locales = require('./i18n');
module.exports = GitBook.createPlugin({
activate: (dispatch, state, { Components, I18n }) => {
- dispatch(Components.registerComponent(Theme, { role: 'Body' }));
+ dispatch(Components.registerComponent(Theme, { role: 'website:body' }));
dispatch(I18n.registerLocales(locales));
},
reduce: reduceState
diff --git a/packages/gitbook-plugin/package.json b/packages/gitbook-plugin/package.json
index c342eef..64cbf6b 100644
--- a/packages/gitbook-plugin/package.json
+++ b/packages/gitbook-plugin/package.json
@@ -1,39 +1,39 @@
{
- "name": "gitbook-plugin",
- "version": "0.0.0",
- "description": "CLI for compiling and testing plugins",
- "main": "./lib/index.js",
- "dependencies": {
- "babel-preset-es2015": "^6.14.0",
- "babel-preset-react": "^6.11.1",
- "babelify": "^7.3.0",
- "browserify": "^13.1.0",
- "commander": "^2.9.0",
- "fs-extra": "^0.30.0",
- "inquirer": "^1.1.3",
- "q": "^1.4.1",
- "winston": "^2.2.0"
- },
- "devDependencies": {
- "babel-cli": "^6.14.0",
- "babel-preset-es2015": "^6.14.0",
- "babel-preset-react": "^6.11.1",
- "babel-preset-stage-2": "^6.13.0"
- },
- "bin": {
- "gitbook-plugin": "./lib/cli.js"
- },
- "scripts": {
- "dist": "rm -rf lib/ && babel -d lib/ src/ && chmod +x ./lib/cli.js",
- "prepublish": "npm run dist"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/GitbookIO/gitbook.git"
- },
- "author": "GitBook Inc. <contact@gitbook.com>",
- "license": "Apache-2.0",
- "bugs": {
- "url": "https://github.com/GitbookIO/gitbook/issues"
- }
-}
+ "name": "gitbook-plugin",
+ "version": "4.0.0",
+ "description": "CLI for compiling and testing plugins",
+ "main": "./lib/index.js",
+ "dependencies": {
+ "babel-preset-es2015": "^6.14.0",
+ "babel-preset-react": "^6.11.1",
+ "babelify": "^7.3.0",
+ "browserify": "^13.1.0",
+ "commander": "^2.9.0",
+ "fs-extra": "^0.30.0",
+ "inquirer": "^1.1.3",
+ "q": "^1.4.1",
+ "winston": "^2.2.0"
+ },
+ "devDependencies": {
+ "babel-cli": "^6.14.0",
+ "babel-preset-es2015": "^6.14.0",
+ "babel-preset-react": "^6.11.1",
+ "babel-preset-stage-2": "^6.13.0"
+ },
+ "bin": {
+ "gitbook-plugin": "./lib/cli.js"
+ },
+ "scripts": {
+ "dist": "rm -rf lib/ && babel -d lib/ src/ && chmod +x ./lib/cli.js",
+ "prepublish": "npm run dist"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/GitbookIO/gitbook.git"
+ },
+ "author": "GitBook Inc. <contact@gitbook.com>",
+ "license": "Apache-2.0",
+ "bugs": {
+ "url": "https://github.com/GitbookIO/gitbook/issues"
+ }
+} \ No newline at end of file
diff --git a/packages/gitbook/package.json b/packages/gitbook/package.json
index 12b190a..01fa93e 100644
--- a/packages/gitbook/package.json
+++ b/packages/gitbook/package.json
@@ -1,110 +1,110 @@
{
- "name": "gitbook",
- "version": "4.0.0",
- "homepage": "https://www.gitbook.com",
- "description": "Library and cmd utility to generate GitBooks",
- "main": "lib/index.js",
- "browser": "./lib/browser.js",
- "dependencies": {
- "bash-color": "0.0.4",
- "cheerio": "0.20.0",
- "chokidar": "1.5.0",
- "cp": "0.2.0",
- "cpr": "1.1.1",
- "crc": "3.4.0",
- "destroy": "1.0.4",
- "direction": "0.1.5",
- "dom-serializer": "0.1.0",
- "error": "7.0.2",
- "escape-html": "^1.0.3",
- "escape-string-regexp": "1.0.5",
- "extend": "^3.0.0",
- "fresh-require": "1.0.3",
- "front-matter": "^2.1.0",
- "gitbook-asciidoc": "1.2.2",
- "gitbook-core": "*",
- "gitbook-markdown": "1.3.2",
- "gitbook-plugin-headings": "1.0.0",
- "gitbook-plugin-highlight": "2.0.2",
- "gitbook-plugin-livereload": "0.0.1",
- "gitbook-plugin-lunr": "1.2.0",
- "gitbook-plugin-search": "2.2.1",
- "gitbook-plugin-sharing": "4.0.0",
- "gitbook-plugin-theme-default": "1.0.5",
- "gitbook-plugin-hints": "2.0.0",
- "github-slugid": "1.0.1",
- "graceful-fs": "4.1.4",
- "i18n-t": "1.0.1",
- "ignore": "3.1.2",
- "immutable": "^3.8.1",
- "is": "^3.1.0",
- "js-yaml": "^3.6.1",
- "json-schema-defaults": "0.1.1",
- "jsonschema": "1.1.0",
- "juice": "2.0.0",
- "mkdirp": "0.5.1",
- "moment": "2.13.0",
- "npm": "3.9.2",
- "npmi": "2.0.1",
- "nunjucks": "2.4.2",
- "nunjucks-do": "1.0.0",
- "object-path": "^0.9.2",
- "omit-keys": "^0.1.0",
- "open": "0.0.5",
- "q": "1.4.1",
- "react": "^15.3.2",
- "react-dom": "^15.3.2",
- "react-redux": "^4.4.5",
- "read-installed": "^4.0.3",
- "redux": "^3.5.2",
- "request": "2.72.0",
- "resolve": "1.1.7",
- "rmdir": "1.2.0",
- "semver": "5.1.0",
- "send": "0.13.2",
- "spawn-cmd": "0.0.2",
- "tiny-lr": "0.2.1",
- "tmp": "0.0.28",
- "urijs": "1.18.0"
- },
- "scripts": {
- "test": "./node_modules/.bin/mocha ./testing/setup.js \"./src/**/*/__tests__/*.js\" --bail --reporter=list --timeout=10000 --compilers js:babel-register",
- "dist": "rm -rf lib/ && babel -d lib/ src/ --source-maps --ignore \"**/*/__tests__/*.js\"",
- "prepublish": "npm run dist"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/GitbookIO/gitbook.git"
- },
- "bin": {
- "gitbook": "./bin/gitbook.js"
- },
- "keywords": [
- "git",
- "book",
- "gitbook"
- ],
- "author": "GitBook Inc. <contact@gitbook.com>",
- "license": "Apache-2.0",
- "bugs": {
- "url": "https://github.com/GitbookIO/gitbook/issues"
- },
- "contributors": [
- {
- "name": "Aaron O'Mullan",
- "email": "aaron@gitbook.com"
- },
- {
- "name": "Samy Pessé",
- "email": "samy@gitbook.com"
- }
- ],
- "devDependencies": {
- "babel-cli": "^6.14.0",
- "babel-preset-es2015": "^6.14.0",
- "babel-preset-react": "^6.11.1",
- "babel-preset-stage-2": "^6.13.0",
- "babel-register": "^6.14.0",
- "mocha": "^3.0.2"
- }
-}
+ "name": "gitbook",
+ "version": "4.0.0",
+ "homepage": "https://www.gitbook.com",
+ "description": "Library and cmd utility to generate GitBooks",
+ "main": "lib/index.js",
+ "browser": "./lib/browser.js",
+ "dependencies": {
+ "bash-color": "0.0.4",
+ "cheerio": "0.20.0",
+ "chokidar": "1.5.0",
+ "cp": "0.2.0",
+ "cpr": "1.1.1",
+ "crc": "3.4.0",
+ "destroy": "1.0.4",
+ "direction": "0.1.5",
+ "dom-serializer": "0.1.0",
+ "error": "7.0.2",
+ "escape-html": "^1.0.3",
+ "escape-string-regexp": "1.0.5",
+ "extend": "^3.0.0",
+ "fresh-require": "1.0.3",
+ "front-matter": "^2.1.0",
+ "gitbook-asciidoc": "1.2.2",
+ "gitbook-core": "4.0.0",
+ "gitbook-markdown": "1.3.2",
+ "gitbook-plugin-headings": "4.0.0",
+ "gitbook-plugin-highlight": "4.0.0",
+ "gitbook-plugin-livereload": "0.0.1",
+ "gitbook-plugin-lunr": "4.0.0",
+ "gitbook-plugin-search": "4.0.0",
+ "gitbook-plugin-sharing": "4.0.0",
+ "gitbook-plugin-theme-default": "4.0.0",
+ "gitbook-plugin-hints": "4.0.0",
+ "github-slugid": "1.0.1",
+ "graceful-fs": "4.1.4",
+ "i18n-t": "1.0.1",
+ "ignore": "3.1.2",
+ "immutable": "^3.8.1",
+ "is": "^3.1.0",
+ "js-yaml": "^3.6.1",
+ "json-schema-defaults": "0.1.1",
+ "jsonschema": "1.1.0",
+ "juice": "2.0.0",
+ "mkdirp": "0.5.1",
+ "moment": "2.13.0",
+ "npm": "3.9.2",
+ "npmi": "2.0.1",
+ "nunjucks": "2.4.2",
+ "nunjucks-do": "1.0.0",
+ "object-path": "^0.9.2",
+ "omit-keys": "^0.1.0",
+ "open": "0.0.5",
+ "q": "1.4.1",
+ "react": "^15.3.2",
+ "react-dom": "^15.3.2",
+ "react-redux": "^4.4.5",
+ "read-installed": "^4.0.3",
+ "redux": "^3.5.2",
+ "request": "2.72.0",
+ "resolve": "1.1.7",
+ "rmdir": "1.2.0",
+ "semver": "5.1.0",
+ "send": "0.13.2",
+ "spawn-cmd": "0.0.2",
+ "tiny-lr": "0.2.1",
+ "tmp": "0.0.28",
+ "urijs": "1.18.0"
+ },
+ "scripts": {
+ "test": "./node_modules/.bin/mocha ./testing/setup.js \"./src/**/*/__tests__/*.js\" --bail --reporter=list --timeout=100000 --compilers js:babel-register",
+ "dist": "rm -rf lib/ && babel -d lib/ src/ --source-maps --ignore \"**/*/__tests__/*.js\"",
+ "prepublish": "npm run dist"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/GitbookIO/gitbook.git"
+ },
+ "bin": {
+ "gitbook": "./bin/gitbook.js"
+ },
+ "keywords": [
+ "git",
+ "book",
+ "gitbook"
+ ],
+ "author": "GitBook Inc. <contact@gitbook.com>",
+ "license": "Apache-2.0",
+ "bugs": {
+ "url": "https://github.com/GitbookIO/gitbook/issues"
+ },
+ "contributors": [
+ {
+ "name": "Aaron O'Mullan",
+ "email": "aaron@gitbook.com"
+ },
+ {
+ "name": "Samy Pessé",
+ "email": "samy@gitbook.com"
+ }
+ ],
+ "devDependencies": {
+ "babel-cli": "^6.14.0",
+ "babel-preset-es2015": "^6.14.0",
+ "babel-preset-react": "^6.11.1",
+ "babel-preset-stage-2": "^6.13.0",
+ "babel-register": "^6.14.0",
+ "mocha": "^3.0.2"
+ }
+} \ No newline at end of file
diff --git a/packages/gitbook/src/browser/loadPlugins.js b/packages/gitbook/src/browser/loadPlugins.js
index 0f26aae..bd8a195 100644
--- a/packages/gitbook/src/browser/loadPlugins.js
+++ b/packages/gitbook/src/browser/loadPlugins.js
@@ -1,18 +1,20 @@
const path = require('path');
/**
- * Load all browser plugins
+ * Load all browser plugins.
+ *
* @param {OrderedMap<Plugin>} plugins
+ * @param {String} type ('browser', 'ebook')
* @return {Array}
*/
-function loadPlugins(plugins) {
+function loadPlugins(plugins, type) {
return plugins
.valueSeq()
- .filter(plugin => plugin.getPackage().has('browser'))
+ .filter(plugin => plugin.getPackage().has(type))
.map(plugin => {
const browserFile = path.resolve(
plugin.getPath(),
- plugin.getPackage().get('browser')
+ plugin.getPackage().get(type)
);
return require(browserFile);
diff --git a/packages/gitbook/src/browser/render.js b/packages/gitbook/src/browser/render.js
index 616b157..d5062c6 100644
--- a/packages/gitbook/src/browser/render.js
+++ b/packages/gitbook/src/browser/render.js
@@ -4,9 +4,7 @@ const GitBook = require('gitbook-core');
const loadPlugins = require('./loadPlugins');
-const BOOTSTRAP_CODE = '(function() { require("gitbook-core").bootstrap() })()';
-
-function HTML({head, innerHTML, payload, scripts}) {
+function HTML({head, innerHTML, payload, scripts, bootstrap}) {
const attrs = head.htmlAttributes.toComponent();
return (
@@ -23,7 +21,7 @@ function HTML({head, innerHTML, payload, scripts}) {
return <script key={script} src={script} />;
})}
<script type="application/payload+json" dangerouslySetInnerHTML={{__html: payload}} />
- <script type="application/javascript" dangerouslySetInnerHTML={{__html: BOOTSTRAP_CODE}} />
+ <script type="application/javascript" dangerouslySetInnerHTML={{__html: bootstrap}} />
{head.script.toComponent()}
</body>
</html>
@@ -33,27 +31,40 @@ HTML.propTypes = {
head: React.PropTypes.object,
innerHTML: React.PropTypes.string,
payload: React.PropTypes.string,
+ bootstrap: React.PropTypes.string,
scripts: React.PropTypes.arrayOf(React.PropTypes.string)
};
/**
- * Render a page
+ * Get bootstrap code for a role
+ * @param {String} role
+ * @return {String}
+ */
+function getBootstrapCode(role) {
+ return `(function() { require("gitbook-core").bootstrap({ role: "${role}" }) })()`;
+}
+
+/**
+ * Render a view using plugins.
+ *
* @param {OrderedMap<String:Plugin>} plugin
* @param {Object} initialState
+ * @param {String} type ("ebook" or "browser")
+ * @param {String} role
* @return {String} html
*/
-function render(plugins, initialState) {
+function render(plugins, initialState, type, role) {
// Load the plugins
- const browserPlugins = loadPlugins(plugins);
+ const browserPlugins = loadPlugins(plugins, type);
const payload = JSON.stringify(initialState);
const context = GitBook.createContext(browserPlugins, initialState);
const scripts = plugins.toList()
- .filter(plugin => plugin.getPackage().has('browser'))
+ .filter(plugin => plugin.getPackage().has(type))
.map(plugin => 'gitbook/plugins/' + plugin.getName() + '.js')
.toArray();
- const el = GitBook.renderWithContext(context);
+ const el = GitBook.renderWithContext(context, { role });
// We're done with the context
context.deactivate();
@@ -69,6 +80,7 @@ function render(plugins, initialState) {
head={head}
innerHTML={innerHTML}
payload={payload}
+ bootstrap={getBootstrapCode(role)}
scripts={['gitbook/core.js'].concat(scripts)}
/>;
diff --git a/packages/gitbook/src/json/encodeState.js b/packages/gitbook/src/json/encodeState.js
index d264835..50e7880 100644
--- a/packages/gitbook/src/json/encodeState.js
+++ b/packages/gitbook/src/json/encodeState.js
@@ -11,13 +11,12 @@ const encodeFile = require('./encodeFile');
* This JSON representation is used as initial state for the redux store.
*
* @param {Output} output
- * @param {Page} page
+ * @param {Page} page?
* @return {JSON}
*/
function encodeStateToJSON(output, page) {
const book = output.getBook();
const urls = output.getURLIndex();
- const file = page.getFile();
return {
output: {
@@ -34,8 +33,8 @@ function encodeStateToJSON(output, page) {
config: book.getConfig().getValues().toJS(),
languages: book.isMultilingual() ? encodeLanguages(book.getLanguages()) : undefined,
- page: encodePage(page, book.getSummary(), urls),
- file: encodeFile(file, urls)
+ page: page ? encodePage(page, book.getSummary(), urls) : undefined,
+ file: page ? encodeFile(page.getFile(), urls) : undefined
};
}
diff --git a/packages/gitbook/src/models/__tests__/page.js b/packages/gitbook/src/models/__tests__/page.js
index ad9420e..b004121 100644
--- a/packages/gitbook/src/models/__tests__/page.js
+++ b/packages/gitbook/src/models/__tests__/page.js
@@ -5,7 +5,7 @@ describe('Page', function() {
describe('toText', function() {
it('must not prepend frontmatter if no attributes', function() {
- const page = Page().merge({
+ const page = (new Page()).merge({
content: 'Hello World'
});
@@ -13,7 +13,7 @@ describe('Page', function() {
});
it('must prepend frontmatter if attributes', function() {
- const page = Page().merge({
+ const page = (new Page()).merge({
content: 'Hello World',
attributes: Immutable.fromJS({
hello: 'world'
@@ -24,4 +24,3 @@ describe('Page', function() {
});
});
});
-
diff --git a/packages/gitbook/src/models/__tests__/templateBlock.js b/packages/gitbook/src/models/__tests__/templateBlock.js
index 20511be..408b57e 100644
--- a/packages/gitbook/src/models/__tests__/templateBlock.js
+++ b/packages/gitbook/src/models/__tests__/templateBlock.js
@@ -5,49 +5,56 @@ const Promise = require('../../utils/promise');
describe('TemplateBlock', function() {
const TemplateBlock = require('../templateBlock');
- describe('create', function() {
+ describe('.create', function() {
it('must initialize a simple TemplateBlock from a function', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
- return {
- body: '<p>Hello, World!</p>',
- parse: true
- };
+ return { message: 'Hello World' };
});
- // Check basic templateBlock properties
expect(templateBlock.getName()).toBe('sayhello');
expect(templateBlock.getEndTag()).toBe('endsayhello');
expect(templateBlock.getBlocks().size).toBe(0);
expect(templateBlock.getExtensionName()).toBe('BlocksayhelloExtension');
+ });
+ });
+
+ describe('.toProps', function() {
+ it('must handle sync method', function() {
+ const templateBlock = TemplateBlock.create('sayhello', function(block) {
+ return { message: 'Hello World' };
+ });
- // Check result of applying block
- return Promise()
- .then(function() {
- return templateBlock.applyBlock();
- })
- .then(function(result) {
- expect(result.name).toBe('sayhello');
- expect(result.body).toBe('<p>Hello, World!</p>');
+ return templateBlock.toProps()
+ .then(function(props) {
+ expect(props).toEqual({ message: 'Hello World' });
+ });
+ });
+
+ it('must not fsil if return a string', function() {
+ const templateBlock = TemplateBlock.create('sayhello', function(block) {
+ return 'Hello World';
+ });
+
+ return templateBlock.toProps()
+ .then(function(props) {
+ expect(props).toEqual({ children: 'Hello World' });
});
});
});
- describe('getShortcuts', function() {
+ describe('.getShortcuts', function() {
it('must return undefined if no shortcuts', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
- return {
- body: '<p>Hello, World!</p>',
- parse: true
- };
+ return { message: 'Hello World' };
});
expect(templateBlock.getShortcuts()).toNotExist();
});
- it('must return complete shortcut', function() {
+ it('.must return complete shortcut', function() {
const templateBlock = TemplateBlock.create('sayhello', {
process(block) {
- return '<p>Hello, World!</p>';
+ return { message: 'Hello World' };
},
shortcuts: {
parsers: ['markdown'],
@@ -66,43 +73,30 @@ describe('TemplateBlock', function() {
});
});
- describe('toNunjucksExt()', function() {
- it('should replace by block anchor', function() {
+ describe('.toNunjucksExt()', function() {
+ it('should render children correctly', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
return 'Hello';
});
- let blocks = {};
-
// Create a fresh Nunjucks environment
const env = new nunjucks.Environment(null, { autoescape: false });
// Add template block to environement
- const Ext = templateBlock.toNunjucksExt({}, blocks);
+ const Ext = templateBlock.toNunjucksExt();
env.addExtension(templateBlock.getExtensionName(), new Ext());
// Render a template using the block
const src = '{% sayhello %}{% endsayhello %}';
return Promise.nfcall(env.renderString.bind(env), src)
.then(function(res) {
- blocks = Immutable.fromJS(blocks);
- expect(blocks.size).toBe(1);
-
- const blockId = blocks.keySeq().get(0);
- const block = blocks.get(blockId);
-
- expect(res).toBe('{{-%' + blockId + '%-}}');
- expect(block.get('body')).toBe('Hello');
- expect(block.get('name')).toBe('sayhello');
+ expect(res).toBe('<xblock name="sayhello" props="{}">Hello</xblock>');
});
});
- it('must create a valid nunjucks extension', function() {
+ it('must handle HTML children', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
- return {
- body: '<p>Hello, World!</p>',
- parse: true
- };
+ return '<p>Hello, World!</p>';
});
// Create a fresh Nunjucks environment
@@ -116,15 +110,14 @@ describe('TemplateBlock', function() {
const src = '{% sayhello %}{% endsayhello %}';
return Promise.nfcall(env.renderString.bind(env), src)
.then(function(res) {
- expect(res).toBe('<p>Hello, World!</p>');
+ expect(res).toBe('<xblock name="sayhello" props="{}"><p>Hello, World!</p></xblock>');
});
});
- it('must apply block arguments correctly', function() {
+ it('must inline props without children', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
return {
- body: '<' + block.kwargs.tag + '>Hello, ' + block.kwargs.name + '!</' + block.kwargs.tag + '>',
- parse: true
+ message: block.kwargs.tag + ' ' + block.kwargs.name
};
});
@@ -139,17 +132,17 @@ describe('TemplateBlock', function() {
const src = '{% sayhello name="Samy", tag="p" %}{% endsayhello %}';
return Promise.nfcall(env.renderString.bind(env), src)
.then(function(res) {
- expect(res).toBe('<p>Hello, Samy!</p>');
+ expect(res).toBe('<xblock name="sayhello" props="{&quot;message&quot;:&quot;p Samy&quot;}"></xblock>');
});
});
it('must accept an async function', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
return Promise()
+ .delay(1)
.then(function() {
return {
- body: 'Hello ' + block.body,
- parse: true
+ children: 'Hello ' + block.children
};
});
});
@@ -165,7 +158,7 @@ describe('TemplateBlock', function() {
const src = '{% sayhello %}Samy{% endsayhello %}';
return Promise.nfcall(env.renderString.bind(env), src)
.then(function(res) {
- expect(res).toBe('Hello Samy');
+ expect(res).toBe('<xblock name="sayhello" props="{}">Hello Samy</xblock>');
});
});
@@ -177,13 +170,10 @@ describe('TemplateBlock', function() {
const nested = {};
block.blocks.forEach(function(blk) {
- nested[blk.name] = blk.body.trim();
+ nested[blk.name] = blk.children.trim();
});
- return {
- body: '<p class="yoda">' + nested.end + ' ' + nested.start + '</p>',
- parse: true
- };
+ return '<p class="yoda">' + nested.end + ' ' + nested.start + '</p>';
}
});
@@ -198,7 +188,7 @@ describe('TemplateBlock', function() {
const src = '{% yoda %}{% start %}this sentence should be{% end %}inverted{% endyoda %}';
return Promise.nfcall(env.renderString.bind(env), src)
.then(function(res) {
- expect(res).toBe('<p class="yoda">inverted this sentence should be</p>');
+ expect(res).toBe('<xblock name="yoda" props="{}"><p class="yoda">inverted this sentence should be</p></xblock>');
});
});
});
diff --git a/packages/gitbook/src/models/__tests__/uriIndex.js b/packages/gitbook/src/models/__tests__/uriIndex.js
index db3b13c..4448683 100644
--- a/packages/gitbook/src/models/__tests__/uriIndex.js
+++ b/packages/gitbook/src/models/__tests__/uriIndex.js
@@ -1,6 +1,6 @@
const URIIndex = require('../uriIndex');
-describe.only('URIIndex', () => {
+describe('URIIndex', () => {
let index;
before(() => {
@@ -40,6 +40,18 @@ describe.only('URIIndex', () => {
});
+ describe('.resolveToURL', () => {
+
+ it('should resolve a basic file path with directory index', () => {
+ expect(index.resolveToURL('README.md')).toBe('./');
+ });
+
+ it('should resolve a basic file path with directory index', () => {
+ expect(index.resolveToURL('hello/README.md')).toBe('hello/');
+ });
+
+ });
+
describe('.resolveFrom', () => {
it('should resolve correctly in same directory', () => {
diff --git a/packages/gitbook/src/models/ignore.js b/packages/gitbook/src/models/ignore.js
index 99ade9a..547f6b4 100644
--- a/packages/gitbook/src/models/ignore.js
+++ b/packages/gitbook/src/models/ignore.js
@@ -1,42 +1,43 @@
-const Immutable = require('immutable');
+const { Record } = require('immutable');
const IgnoreMutable = require('ignore');
/*
Immutable version of node-ignore
*/
-const Ignore = Immutable.Record({
- ignore: new IgnoreMutable()
-}, 'Ignore');
-
-Ignore.prototype.getIgnore = function() {
- return this.get('ignore');
-};
-/**
- Test if a file is ignored by these rules
-
- @param {String} filePath
- @return {Boolean}
-*/
-Ignore.prototype.isFileIgnored = function(filename) {
- const ignore = this.getIgnore();
- return ignore.filter([filename]).length == 0;
+const DEFAULTS = {
+ ignore: new IgnoreMutable()
};
-/**
- Add rules
-
- @param {String}
- @return {Ignore}
-*/
-Ignore.prototype.add = function(rule) {
- const ignore = this.getIgnore();
- const newIgnore = new IgnoreMutable();
-
- newIgnore.add(ignore);
- newIgnore.add(rule);
-
- return this.set('ignore', newIgnore);
-};
+class Ignore extends Record(DEFAULTS) {
+ getIgnore() {
+ return this.get('ignore');
+ }
+
+ /**
+ * Test if a file is ignored by these rules.
+ * @param {String} filePath
+ * @return {Boolean} isIgnored
+ */
+ isFileIgnored(filename) {
+ const ignore = this.getIgnore();
+ return ignore.filter([filename]).length == 0;
+ }
+
+ /**
+ * Add rules.
+ * @param {String}
+ * @return {Ignore}
+ */
+ add(rule) {
+ const ignore = this.getIgnore();
+ const newIgnore = new IgnoreMutable();
+
+ newIgnore.add(ignore);
+ newIgnore.add(rule);
+
+ return this.set('ignore', newIgnore);
+ }
+}
module.exports = Ignore;
diff --git a/packages/gitbook/src/models/templateBlock.js b/packages/gitbook/src/models/templateBlock.js
index e8d2aae..61c006f 100644
--- a/packages/gitbook/src/models/templateBlock.js
+++ b/packages/gitbook/src/models/templateBlock.js
@@ -1,6 +1,6 @@
const is = require('is');
const extend = require('extend');
-const Immutable = require('immutable');
+const { Record, List, Map } = require('immutable');
const escape = require('escape-html');
const Promise = require('../utils/promise');
@@ -9,232 +9,236 @@ const TemplateShortcut = require('./templateShortcut');
const NODE_ENDARGS = '%%endargs%%';
const HTML_TAGNAME = 'xblock';
-const TemplateBlock = Immutable.Record({
+const DEFAULTS = {
// Name of block, also the start tag
- name: String(),
-
+ name: String(),
// End tag, default to "end<name>"
- end: String(),
-
+ end: String(),
// Function to process the block content
- process: Function(),
-
+ process: Function(),
// List of String, for inner block tags
- blocks: Immutable.List(),
-
+ blocks: List(),
// List of shortcuts to replace with this block
- shortcuts: Immutable.Map()
-}, 'TemplateBlock');
-
-TemplateBlock.prototype.getName = function() {
- return this.get('name');
-};
-
-TemplateBlock.prototype.getEndTag = function() {
- return this.get('end') || ('end' + this.getName());
+ shortcuts: Map()
};
-TemplateBlock.prototype.getProcess = function() {
- return this.get('process');
-};
-
-TemplateBlock.prototype.getBlocks = function() {
- return this.get('blocks');
-};
-
-
-/**
- * Return shortcuts associated with this block or undefined
- * @return {TemplateShortcut|undefined}
- */
-TemplateBlock.prototype.getShortcuts = function() {
- const shortcuts = this.get('shortcuts');
- if (shortcuts.size === 0) {
- return undefined;
+class TemplateBlock extends Record(DEFAULTS) {
+ getName() {
+ return this.get('name');
}
- return TemplateShortcut.createForBlock(this, shortcuts);
-};
-
-/**
- * Return name for the nunjucks extension
- * @return {String}
- */
-TemplateBlock.prototype.getExtensionName = function() {
- return 'Block' + this.getName() + 'Extension';
-};
-
-/**
- * Return a nunjucks extension to represents this block
- * @return {Nunjucks.Extension}
- */
-TemplateBlock.prototype.toNunjucksExt = function(mainContext, blocksOutput) {
- blocksOutput = blocksOutput || {};
-
- const that = this;
- const name = this.getName();
- const endTag = this.getEndTag();
- const blocks = this.getBlocks().toJS();
-
- function Ext() {
- this.tags = [name];
-
- this.parse = function(parser, nodes) {
- let lastBlockName = null;
- let lastBlockArgs = null;
- const allBlocks = blocks.concat([endTag]);
-
- // Parse first block
- const tok = parser.nextToken();
- lastBlockArgs = parser.parseSignature(null, true);
- parser.advanceAfterBlockEnd(tok.value);
-
- const args = new nodes.NodeList();
- const bodies = [];
- const blockNamesNode = new nodes.Array(tok.lineno, tok.colno);
- const blockArgCounts = new nodes.Array(tok.lineno, tok.colno);
-
- // Parse while we found "end<block>"
- do {
- // Read body
- const currentBody = parser.parseUntilBlocks(...allBlocks);
-
- // Handle body with previous block name and args
- blockNamesNode.addChild(new nodes.Literal(args.lineno, args.colno, lastBlockName));
- blockArgCounts.addChild(new nodes.Literal(args.lineno, args.colno, lastBlockArgs.children.length));
- bodies.push(currentBody);
-
- // Append arguments of this block as arguments of the run function
- lastBlockArgs.children.forEach(function(child) {
- args.addChild(child);
- });
-
- // Read new block
- lastBlockName = parser.nextToken().value;
-
- // Parse signature and move to the end of the block
- if (lastBlockName != endTag) {
- lastBlockArgs = parser.parseSignature(null, true);
- }
-
- parser.advanceAfterBlockEnd(lastBlockName);
- } while (lastBlockName != endTag);
-
- args.addChild(blockNamesNode);
- args.addChild(blockArgCounts);
- args.addChild(new nodes.Literal(args.lineno, args.colno, NODE_ENDARGS));
-
- return new nodes.CallExtensionAsync(this, 'run', args, bodies);
- };
-
- this.run = function(context, ...fnArgs) {
- let args;
- const blocks = [];
- let bodies = [];
+ getEndTag() {
+ return this.get('end') || ('end' + this.getName());
+ }
- // Extract callback
- const callback = fnArgs.pop();
+ getProcess() {
+ return this.get('process');
+ }
- // Detect end of arguments
- const endArgIndex = fnArgs.indexOf(NODE_ENDARGS);
+ getBlocks() {
+ return this.get('blocks');
+ }
- // Extract arguments and bodies
- args = fnArgs.slice(0, endArgIndex);
- bodies = fnArgs.slice(endArgIndex + 1);
- // Extract block counts
- const blockArgCounts = args.pop();
- const blockNames = args.pop();
+ /**
+ * Return shortcuts associated with this block or undefined
+ * @return {TemplateShortcut|undefined}
+ */
+ getShortcuts() {
+ const shortcuts = this.get('shortcuts');
+ if (shortcuts.size === 0) {
+ return undefined;
+ }
- // Recreate list of blocks
- blockNames.forEach((blkName, i) => {
- const countArgs = blockArgCounts[i];
- const blockBody = bodies.shift();
+ return TemplateShortcut.createForBlock(this, shortcuts);
+ }
- const blockArgs = countArgs > 0 ? args.slice(0, countArgs) : [];
- args = args.slice(countArgs);
- const blockKwargs = extractKwargs(blockArgs);
+ /**
+ * Return name for the nunjucks extension
+ * @return {String}
+ */
+ getExtensionName() {
+ return 'Block' + this.getName() + 'Extension';
+ }
- blocks.push({
- name: blkName,
- children: blockBody(),
- args: blockArgs,
- kwargs: blockKwargs
+ /**
+ * Return a nunjucks extension to represents this block
+ * @return {Nunjucks.Extension}
+ */
+ toNunjucksExt(mainContext = {}) {
+ const that = this;
+ const name = this.getName();
+ const endTag = this.getEndTag();
+ const blocks = this.getBlocks().toJS();
+
+ function Ext() {
+ this.tags = [name];
+
+ this.parse = (parser, nodes) => {
+ let lastBlockName = null;
+ let lastBlockArgs = null;
+ const allBlocks = blocks.concat([endTag]);
+
+ // Parse first block
+ const tok = parser.nextToken();
+ lastBlockArgs = parser.parseSignature(null, true);
+ parser.advanceAfterBlockEnd(tok.value);
+
+ const args = new nodes.NodeList();
+ const bodies = [];
+ const blockNamesNode = new nodes.Array(tok.lineno, tok.colno);
+ const blockArgCounts = new nodes.Array(tok.lineno, tok.colno);
+
+ // Parse while we found "end<block>"
+ do {
+ // Read body
+ const currentBody = parser.parseUntilBlocks(...allBlocks);
+
+ // Handle body with previous block name and args
+ blockNamesNode.addChild(new nodes.Literal(args.lineno, args.colno, lastBlockName));
+ blockArgCounts.addChild(new nodes.Literal(args.lineno, args.colno, lastBlockArgs.children.length));
+ bodies.push(currentBody);
+
+ // Append arguments of this block as arguments of the run function
+ lastBlockArgs.children.forEach(function(child) {
+ args.addChild(child);
+ });
+
+ // Read new block
+ lastBlockName = parser.nextToken().value;
+
+ // Parse signature and move to the end of the block
+ if (lastBlockName != endTag) {
+ lastBlockArgs = parser.parseSignature(null, true);
+ }
+
+ parser.advanceAfterBlockEnd(lastBlockName);
+ } while (lastBlockName != endTag);
+
+ args.addChild(blockNamesNode);
+ args.addChild(blockArgCounts);
+ args.addChild(new nodes.Literal(args.lineno, args.colno, NODE_ENDARGS));
+
+ return new nodes.CallExtensionAsync(this, 'run', args, bodies);
+ };
+
+ this.run = (context, ...fnArgs) => {
+ let args;
+ const blocks = [];
+ let bodies = [];
+
+ // Extract callback
+ const callback = fnArgs.pop();
+
+ // Detect end of arguments
+ const endArgIndex = fnArgs.indexOf(NODE_ENDARGS);
+
+ // Extract arguments and bodies
+ args = fnArgs.slice(0, endArgIndex);
+ bodies = fnArgs.slice(endArgIndex + 1);
+
+ // Extract block counts
+ const blockArgCounts = args.pop();
+ const blockNames = args.pop();
+
+ // Recreate list of blocks
+ blockNames.forEach((blkName, i) => {
+ const countArgs = blockArgCounts[i];
+ const blockBody = bodies.shift();
+
+ const blockArgs = countArgs > 0 ? args.slice(0, countArgs) : [];
+ args = args.slice(countArgs);
+ const blockKwargs = extractKwargs(blockArgs);
+
+ blocks.push({
+ name: blkName,
+ children: blockBody(),
+ args: blockArgs,
+ kwargs: blockKwargs
+ });
});
- });
- const mainBlock = blocks.shift();
- mainBlock.blocks = blocks;
-
- Promise()
- .then(function() {
- const ctx = extend({
- ctx: context
- }, mainContext || {});
-
- return that.applyBlock(mainBlock, ctx);
- })
- .then(function(props) {
- return that.blockResultToHtml(props);
- })
- .nodeify(callback);
- };
+ const mainBlock = blocks.shift();
+ mainBlock.blocks = blocks;
+
+ Promise()
+ .then(function() {
+ const ctx = extend({
+ ctx: context
+ }, mainContext);
+
+ return that.toProps(mainBlock, ctx);
+ })
+ .then(function(props) {
+ return that.toHTML(props);
+ })
+ .nodeify(callback);
+ };
+ }
+
+ return Ext;
}
- return Ext;
-};
-
-/**
- * Apply a block to a content.
- *
- * @param {Object} inner
- * @param {Object} context
- * @return {Promise<Props>|Props}
- */
-TemplateBlock.prototype.applyBlock = function(inner, context) {
- const processFn = this.getProcess();
-
- inner = inner || {};
- inner.args = inner.args || [];
- inner.kwargs = inner.kwargs || {};
- inner.blocks = inner.blocks || [];
-
- return processFn.call(context, inner);
-};
+ /**
+ * Apply a block an return the props
+ *
+ * @param {Object} inner
+ * @param {Object} context
+ * @return {Promise<Props>}
+ */
+ toProps(inner, context) {
+ const processFn = this.getProcess();
+
+ inner = inner || {};
+ inner.args = inner.args || [];
+ inner.kwargs = inner.kwargs || {};
+ inner.blocks = inner.blocks || [];
+
+ return Promise()
+ .then(() => processFn.call(context, inner))
+ .then(props => {
+ if (is.string(props)) {
+ return { children: props };
+ }
+
+ return props;
+ });
+ }
-/**
- * Convert a block props to HTML. This HTML is then being
- * parsed by gitbook-core during rendering, and binded to the right react components.
- *
- * @param {Object} props
- * @return {String}
- */
-TemplateBlock.prototype.blockResultToHtml = function(props) {
- const { children, ...innerProps } = props;
- const payload = escape(JSON.stringify(innerProps));
+ /**
+ * Convert a block props to HTML. This HTML is then being
+ * parsed by gitbook-core during rendering, and binded to the right react components.
+ *
+ * @param {Object} props
+ * @return {String}
+ */
+ toHTML(props) {
+ const { children, ...innerProps } = props;
+ const payload = escape(JSON.stringify(innerProps));
+
+ return (
+ `<${HTML_TAGNAME} name="${this.name}" props="${payload}">${children || ''}</${HTML_TAGNAME}>`
+ );
+ }
- return (
- `<${HTML_TAGNAME} name="${this.name}" props="${payload}">${children}</${HTML_TAGNAME}>`
- );
-};
+ /**
+ * Create a template block from a function or an object
+ * @param {String} blockName
+ * @param {Object} block
+ * @return {TemplateBlock}
+ */
+ static create(blockName, block) {
+ if (is.fn(block)) {
+ block = new Map({
+ process: block
+ });
+ }
-/**
- * Create a template block from a function or an object
- * @param {String} blockName
- * @param {Object} block
- * @return {TemplateBlock}
- */
-TemplateBlock.create = function(blockName, block) {
- if (is.fn(block)) {
- block = new Immutable.Map({
- process: block
- });
+ block = new TemplateBlock(block);
+ block = block.set('name', blockName);
+ return block;
}
-
- block = new TemplateBlock(block);
- block = block.set('name', blockName);
- return block;
-};
+}
/**
* Extract kwargs from an arguments array
diff --git a/packages/gitbook/src/models/templateEngine.js b/packages/gitbook/src/models/templateEngine.js
index b218a9d..0d0dcb6 100644
--- a/packages/gitbook/src/models/templateEngine.js
+++ b/packages/gitbook/src/models/templateEngine.js
@@ -1,139 +1,133 @@
const nunjucks = require('nunjucks');
-const Immutable = require('immutable');
-
-const TemplateEngine = Immutable.Record({
- // Map of {TemplateBlock}
- blocks: Immutable.Map(),
+const { Record, Map, List } = require('immutable');
+const DEFAULTS = {
+ // List of {TemplateBlock}
+ blocks: List(),
// Map of Extension
- extensions: Immutable.Map(),
-
+ extensions: Map(),
// Map of filters: {String} name -> {Function} fn
- filters: Immutable.Map(),
-
+ filters: Map(),
// Map of globals: {String} name -> {Mixed}
- globals: Immutable.Map(),
-
+ globals: Map(),
// Context for filters / blocks
context: Object(),
-
// Nunjucks loader
loader: nunjucks.FileSystemLoader('views')
-}, 'TemplateEngine');
-
-TemplateEngine.prototype.getBlocks = function() {
- return this.get('blocks');
-};
-
-TemplateEngine.prototype.getGlobals = function() {
- return this.get('globals');
};
-TemplateEngine.prototype.getFilters = function() {
- return this.get('filters');
-};
-
-TemplateEngine.prototype.getShortcuts = function() {
- return this.get('shortcuts');
-};
-
-TemplateEngine.prototype.getLoader = function() {
- return this.get('loader');
-};
-
-TemplateEngine.prototype.getContext = function() {
- return this.get('context');
-};
-
-TemplateEngine.prototype.getExtensions = function() {
- return this.get('extensions');
-};
-
-/**
- Return a block by its name (or undefined)
-
- @param {String} name
- @return {TemplateBlock}
-*/
-TemplateEngine.prototype.getBlock = function(name) {
- const blocks = this.getBlocks();
- return blocks.find(function(block) {
- return block.getName() === name;
- });
-};
-
-/**
- Return a nunjucks environment from this configuration
-
- @return {Nunjucks.Environment}
-*/
-TemplateEngine.prototype.toNunjucks = function(blocksOutput) {
- const loader = this.getLoader();
- const blocks = this.getBlocks();
- const filters = this.getFilters();
- const globals = this.getGlobals();
- const extensions = this.getExtensions();
- const context = this.getContext();
-
- const env = new nunjucks.Environment(
- loader,
- {
- // Escaping is done after by the asciidoc/markdown parser
- autoescape: false,
-
- // Syntax
- tags: {
- blockStart: '{%',
- blockEnd: '%}',
- variableStart: '{{',
- variableEnd: '}}',
- commentStart: '{###',
- commentEnd: '###}'
+class TemplateEngine extends Record(DEFAULTS) {
+ getBlocks() {
+ return this.get('blocks');
+ }
+
+ getGlobals() {
+ return this.get('globals');
+ }
+
+ getFilters() {
+ return this.get('filters');
+ }
+
+ getShortcuts() {
+ return this.get('shortcuts');
+ }
+
+ getLoader() {
+ return this.get('loader');
+ }
+
+ getContext() {
+ return this.get('context');
+ }
+
+ getExtensions() {
+ return this.get('extensions');
+ }
+
+ /**
+ * Return a block by its name (or undefined).
+ * @param {String} name
+ * @return {TemplateBlock} block?
+ */
+ getBlock(name) {
+ const blocks = this.getBlocks();
+ return blocks.find(function(block) {
+ return block.getName() === name;
+ });
+ }
+
+ /**
+ * Return a nunjucks environment from this configuration
+ * @return {Nunjucks.Environment} env
+ */
+ toNunjucks() {
+ const loader = this.getLoader();
+ const blocks = this.getBlocks();
+ const filters = this.getFilters();
+ const globals = this.getGlobals();
+ const extensions = this.getExtensions();
+ const context = this.getContext();
+
+ const env = new nunjucks.Environment(
+ loader,
+ {
+ // Escaping is done after by the asciidoc/markdown parser
+ autoescape: false,
+
+ // Syntax
+ tags: {
+ blockStart: '{%',
+ blockEnd: '%}',
+ variableStart: '{{',
+ variableEnd: '}}',
+ commentStart: '{###',
+ commentEnd: '###}'
+ }
}
- }
- );
-
- // Add filters
- filters.forEach(function(filterFn, filterName) {
- env.addFilter(filterName, filterFn.bind(context));
- });
-
- // Add blocks
- blocks.forEach(function(block) {
- const extName = block.getExtensionName();
- const Ext = block.toNunjucksExt(context, blocksOutput);
-
- env.addExtension(extName, new Ext());
- });
-
- // Add globals
- globals.forEach(function(globalValue, globalName) {
- env.addGlobal(globalName, globalValue);
- });
-
- // Add other extensions
- extensions.forEach(function(ext, extName) {
- env.addExtension(extName, ext);
- });
-
- return env;
-};
-
-/**
- Create a template engine
-
- @param {Object} def
- @return {TemplateEngine}
-*/
-TemplateEngine.create = function(def) {
- return new TemplateEngine({
- blocks: Immutable.List(def.blocks || []),
- extensions: Immutable.Map(def.extensions || {}),
- filters: Immutable.Map(def.filters || {}),
- globals: Immutable.Map(def.globals || {}),
- context: def.context,
- loader: def.loader
- });
-};
+ );
+
+ // Add filters
+ filters.forEach(function(filterFn, filterName) {
+ env.addFilter(filterName, filterFn.bind(context));
+ });
+
+ // Add blocks
+ blocks.forEach(function(block) {
+ const extName = block.getExtensionName();
+ const Ext = block.toNunjucksExt(context);
+
+ env.addExtension(extName, new Ext());
+ });
+
+ // Add globals
+ globals.forEach(function(globalValue, globalName) {
+ env.addGlobal(globalName, globalValue);
+ });
+
+ // Add other extensions
+ extensions.forEach(function(ext, extName) {
+ env.addExtension(extName, ext);
+ });
+
+ return env;
+ }
+
+ /**
+ * Create a template engine.
+ * @param {Object} def
+ * @return {TemplateEngine} engine
+ */
+ static create(def) {
+ return new TemplateEngine({
+ blocks: List(def.blocks || []),
+ extensions: Map(def.extensions || {}),
+ filters: Map(def.filters || {}),
+ globals: Map(def.globals || {}),
+ context: def.context,
+ loader: def.loader
+ });
+ }
+}
module.exports = TemplateEngine;
diff --git a/packages/gitbook/src/models/templateOutput.js b/packages/gitbook/src/models/templateOutput.js
deleted file mode 100644
index c6ff730..0000000
--- a/packages/gitbook/src/models/templateOutput.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const Immutable = require('immutable');
-
-const TemplateOutput = Immutable.Record({
- // Text content of the template
- content: String(),
-
- // Map of blocks to replace / post process
- blocks: Immutable.Map()
-}, 'TemplateOutput');
-
-TemplateOutput.prototype.getContent = function() {
- return this.get('content');
-};
-
-TemplateOutput.prototype.getBlocks = function() {
- return this.get('blocks');
-};
-
-/**
- * Update content of this output
- * @param {String} content
- * @return {TemplateContent}
- */
-TemplateOutput.prototype.setContent = function(content) {
- return this.set('content', content);
-};
-
-/**
- * Create a TemplateOutput from a text content
- * and an object containing block definition
- * @param {String} content
- * @param {Object} blocks
- * @return {TemplateOutput}
- */
-TemplateOutput.create = function(content, blocks) {
- return new TemplateOutput({
- content,
- blocks: Immutable.fromJS(blocks)
- });
-};
-
-module.exports = TemplateOutput;
diff --git a/packages/gitbook/src/output/__tests__/generateMock.js b/packages/gitbook/src/output/__tests__/generateMock.js
index a0be244..6ae1de2 100644
--- a/packages/gitbook/src/output/__tests__/generateMock.js
+++ b/packages/gitbook/src/output/__tests__/generateMock.js
@@ -29,7 +29,7 @@ function generateMock(Generator, files) {
book = book.setLogLevel('disabled');
return parseBook(book)
- .then(function(resultBook) {
+ .then((resultBook) => {
return generateBook(Generator, resultBook, {
root: dir.name
});
diff --git a/packages/gitbook/src/output/ebook/getPDFTemplate.js b/packages/gitbook/src/output/ebook/getPDFTemplate.js
index c0faed3..53c7a82 100644
--- a/packages/gitbook/src/output/ebook/getPDFTemplate.js
+++ b/packages/gitbook/src/output/ebook/getPDFTemplate.js
@@ -1,40 +1,35 @@
const juice = require('juice');
-const WebsiteGenerator = require('../website');
const JSONUtils = require('../../json');
-const Templating = require('../../templating');
+const render = require('../../browser/render');
const Promise = require('../../utils/promise');
-
/**
- Generate PDF header/footer templates
-
- @param {Output} output
- @param {String} type
- @return {String}
-*/
+ * Generate PDF header/footer templates
+ *
+ * @param {Output} output
+ * @param {String} type ("footer" or "header")
+ * @return {String} html
+ */
function getPDFTemplate(output, type) {
- const filePath = 'pdf_' + type + '.html';
const outputRoot = output.getRoot();
- const engine = WebsiteGenerator.createTemplateEngine(output, filePath);
+ const plugins = output.getPlugins();
- // Generate context
- const context = JSONUtils.encodeOutput(output);
- context.page = {
+ // Generate initial state
+ const initialState = JSONUtils.encodeState(output);
+ initialState.page = {
num: '_PAGENUM_',
title: '_SECTION_'
};
// Render the theme
- return Templating.renderFile(engine, 'ebook/' + filePath, context)
+ const html = render(plugins, initialState, 'ebook', `pdf:${type}`);
- // Inline css and assets
- .then(function(tplOut) {
- return Promise.nfcall(juice.juiceResources, tplOut.getContent(), {
- webResources: {
- relativeTo: outputRoot
- }
- });
+ // Inline CSS
+ return Promise.nfcall(juice.juiceResources, html, {
+ webResources: {
+ relativeTo: outputRoot
+ }
});
}
diff --git a/packages/gitbook/src/output/ebook/onFinish.js b/packages/gitbook/src/output/ebook/onFinish.js
index adff798..7db757f 100644
--- a/packages/gitbook/src/output/ebook/onFinish.js
+++ b/packages/gitbook/src/output/ebook/onFinish.js
@@ -1,45 +1,39 @@
const path = require('path');
-const WebsiteGenerator = require('../website');
const JSONUtils = require('../../json');
-const Templating = require('../../templating');
const Promise = require('../../utils/promise');
const error = require('../../utils/error');
const command = require('../../utils/command');
const writeFile = require('../helper/writeFile');
+const render = require('../../browser/render');
const getConvertOptions = require('./getConvertOptions');
const SUMMARY_FILE = 'SUMMARY.html';
/**
- Write the SUMMARY.html
-
- @param {Output}
- @return {Output}
-*/
+ * Write the SUMMARY.html
+ *
+ * @param {Output} output
+ * @return {Output} output
+ */
function writeSummary(output) {
- const options = output.getOptions();
- const prefix = options.get('prefix');
+ const plugins = output.getPlugins();
- const filePath = SUMMARY_FILE;
- const engine = WebsiteGenerator.createTemplateEngine(output, filePath);
- const context = JSONUtils.encodeOutput(output);
+ // Generate initial state
+ const initialState = JSONUtils.encodeState(output);
- // Render the theme
- return Templating.renderFile(engine, prefix + '/summary.html', context)
+ // Render using React
+ const html = render(plugins, initialState, 'ebook', 'ebook:summary');
- // Write it to the disk
- .then(function(tplOut) {
- return writeFile(output, filePath, tplOut.getContent());
- });
+ return writeFile(output, SUMMARY_FILE, html);
}
/**
- Generate the ebook file as "index.pdf"
-
- @param {Output}
- @return {Output}
-*/
+ * Generate the ebook file as "index.pdf"
+ *
+ * @param {Output} output
+ * @return {Output} output
+ */
function runEbookConvert(output) {
const logger = output.getLogger();
const options = output.getOptions();
@@ -78,11 +72,11 @@ function runEbookConvert(output) {
}
/**
- Finish the generation, generates the SUMMARY.html
-
- @param {Output}
- @return {Output}
-*/
+ * Finish the generation, generates the SUMMARY.html
+ *
+ * @param {Output} output
+ * @return {Output} output
+ */
function onFinish(output) {
return writeSummary(output)
.then(runEbookConvert);
diff --git a/packages/gitbook/src/output/ebook/onPage.js b/packages/gitbook/src/output/ebook/onPage.js
index 520d296..a7c2137 100644
--- a/packages/gitbook/src/output/ebook/onPage.js
+++ b/packages/gitbook/src/output/ebook/onPage.js
@@ -2,11 +2,12 @@ const WebsiteGenerator = require('../website');
const Modifiers = require('../modifiers');
/**
- Write a page for ebook output
-
- @param {Output} output
- @param {Output}
-*/
+ * Write a page for ebook output. It renders it just as the website generator
+ * except that it inline assets.
+ *
+ * @param {Output} output
+ * @param {Output} output
+ */
function onPage(output, page) {
const options = output.getOptions();
diff --git a/packages/gitbook/src/output/ebook/options.js b/packages/gitbook/src/output/ebook/options.js
index 4156fac..d192fd2 100644
--- a/packages/gitbook/src/output/ebook/options.js
+++ b/packages/gitbook/src/output/ebook/options.js
@@ -2,16 +2,13 @@ const Immutable = require('immutable');
const Options = Immutable.Record({
// Root folder for the output
- root: String(),
-
+ root: String(),
// Prefix for generation
- prefix: String('ebook'),
-
+ prefix: String('ebook'),
// Format to generate using ebook-convert
- format: String(),
-
+ format: String(),
// Force use of absolute urls ("index.html" instead of "/")
- directoryIndex: Boolean(false)
+ directoryIndex: Boolean(false)
});
module.exports = Options;
diff --git a/packages/gitbook/src/output/generateBook.js b/packages/gitbook/src/output/generateBook.js
index e27d3ce..0e2c230 100644
--- a/packages/gitbook/src/output/generateBook.js
+++ b/packages/gitbook/src/output/generateBook.js
@@ -58,7 +58,7 @@ function processOutput(generator, startOutput) {
)
)
- .then(function(output) {
+ .then((output) => {
if (!generator.onInit) {
return output;
}
@@ -69,7 +69,7 @@ function processOutput(generator, startOutput) {
.then(generateAssets.bind(null, generator))
.then(generatePages.bind(null, generator))
- .tap(function(output) {
+ .tap((output) => {
const book = output.getBook();
if (!book.isMultilingual()) {
@@ -111,7 +111,7 @@ function processOutput(generator, startOutput) {
)
)
- .then(function(output) {
+ .then((output) => {
if (!generator.onFinish) {
return output;
}
diff --git a/packages/gitbook/src/output/generatePage.js b/packages/gitbook/src/output/generatePage.js
index 671ac54..7375f1d 100644
--- a/packages/gitbook/src/output/generatePage.js
+++ b/packages/gitbook/src/output/generatePage.js
@@ -39,37 +39,26 @@ function generatePage(output, page) {
return callPageHook('page:before', output, resultPage)
// Escape code blocks with raw tags
- .then(function(currentPage) {
+ .then((currentPage) => {
return parser.preparePage(currentPage.getContent());
})
// Render templating syntax
- .then(function(content) {
+ .then((content) => {
const absoluteFilePath = path.join(book.getContentRoot(), filePath);
return Templating.render(engine, absoluteFilePath, content, context);
})
- .then(function(output) {
- const content = output.getContent();
-
- return parser.parsePage(content)
- .then(function(result) {
- return output.setContent(result.content);
- });
- })
-
- // Post processing for templating syntax
- .then(function(output) {
- return Templating.postRender(engine, output);
- })
+ // Parse with markdown/asciidoc parser
+ .then((content) => parser.parsePage(content))
// Return new page
- .then(function(content) {
+ .then(({content}) => {
return resultPage.set('content', content);
})
// Call final hook
- .then(function(currentPage) {
+ .then((currentPage) => {
return callPageHook('page', output, currentPage);
});
})
diff --git a/packages/gitbook/src/output/website/onPage.js b/packages/gitbook/src/output/website/onPage.js
index 7dd35f3..90eec63 100644
--- a/packages/gitbook/src/output/website/onPage.js
+++ b/packages/gitbook/src/output/website/onPage.js
@@ -24,7 +24,7 @@ function onPage(output, page) {
const initialState = JSONUtils.encodeState(output, resultPage);
// Render the theme
- const html = render(plugins, initialState);
+ const html = render(plugins, initialState, 'browser', 'website:body');
// Write it to the disk
return writeFile(output, filePath, html);
diff --git a/packages/gitbook/src/parse/__tests__/parseURIIndexFromPages.js b/packages/gitbook/src/parse/__tests__/parseURIIndexFromPages.js
index e3b9b55..755b225 100644
--- a/packages/gitbook/src/parse/__tests__/parseURIIndexFromPages.js
+++ b/packages/gitbook/src/parse/__tests__/parseURIIndexFromPages.js
@@ -3,7 +3,7 @@ const { OrderedMap } = require('immutable');
const parseURIIndexFromPages = require('../parseURIIndexFromPages');
const Page = require('../../models/page');
-describe.only('parseURIIndexFromPages', () => {
+describe('parseURIIndexFromPages', () => {
it('should map file to html', () => {
const pages = OrderedMap({
@@ -14,24 +14,13 @@ describe.only('parseURIIndexFromPages', () => {
expect(urls.resolve('page.md')).toBe('page.html');
});
- it('should map README to index.html (directoryIndex: false)', () => {
- const pages = OrderedMap({
- 'hello/README.md': new Page()
- });
- const urls = parseURIIndexFromPages(pages, {
- directoryIndex: false
- });
-
- expect(urls.resolve('hello/README.md')).toBe('hello/index.html');
- });
-
it('should map README to folder', () => {
const pages = OrderedMap({
'hello/README.md': new Page()
});
const urls = parseURIIndexFromPages(pages);
- expect(urls.resolve('hello/README.md')).toBe('hello/');
+ expect(urls.resolveToURL('hello/README.md')).toBe('hello/');
});
});
diff --git a/packages/gitbook/src/templating/__tests__/conrefsLoader.js b/packages/gitbook/src/templating/__tests__/conrefsLoader.js
index 431d0a3..18dd5dd 100644
--- a/packages/gitbook/src/templating/__tests__/conrefsLoader.js
+++ b/packages/gitbook/src/templating/__tests__/conrefsLoader.js
@@ -4,30 +4,34 @@ const TemplateEngine = require('../../models/templateEngine');
const renderTemplate = require('../render');
const ConrefsLoader = require('../conrefsLoader');
-describe('ConrefsLoader', function() {
+describe('ConrefsLoader', () => {
const dirName = __dirname + '/';
const fileName = path.join(dirName, 'test.md');
- describe('Git', function() {
- const engine = TemplateEngine({
- loader: new ConrefsLoader(dirName)
+ describe('Git', () => {
+ let engine;
+
+ before(() => {
+ engine = new TemplateEngine({
+ loader: new ConrefsLoader(dirName)
+ });
});
- it('should include content from git', function() {
+ it('should include content from git', () => {
return renderTemplate(engine, fileName, '{% include "git+https://gist.github.com/69ea4542e4c8967d2fa7.git/test.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('Hello from git');
});
});
- it('should handle deep inclusion (1)', function() {
+ it('should handle deep inclusion (1)', () => {
return renderTemplate(engine, fileName, '{% include "git+https://gist.github.com/69ea4542e4c8967d2fa7.git/test2.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('First Hello. Hello from git');
});
});
- it('should handle deep inclusion (2)', function() {
+ it('should handle deep inclusion (2)', () => {
return renderTemplate(engine, fileName, '{% include "git+https://gist.github.com/69ea4542e4c8967d2fa7.git/test3.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('First Hello. Hello from git');
@@ -35,20 +39,24 @@ describe('ConrefsLoader', function() {
});
});
- describe('Local', function() {
- const engine = TemplateEngine({
- loader: new ConrefsLoader(dirName)
+ describe('Local', () => {
+ let engine;
+
+ before(() => {
+ engine = new TemplateEngine({
+ loader: new ConrefsLoader(dirName)
+ });
});
- describe('Relative', function() {
- it('should resolve basic relative filepath', function() {
+ describe('Relative', () => {
+ it('should resolve basic relative filepath', () => {
return renderTemplate(engine, fileName, '{% include "include.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('Hello World');
});
});
- it('should resolve basic parent filepath', function() {
+ it('should resolve basic parent filepath', () => {
return renderTemplate(engine, path.join(dirName, 'hello/test.md'), '{% include "../include.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('Hello World');
@@ -57,23 +65,24 @@ describe('ConrefsLoader', function() {
});
describe('Absolute', function() {
- it('should resolve absolute filepath', function() {
+ it('should resolve absolute filepath', () => {
return renderTemplate(engine, fileName, '{% include "/include.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('Hello World');
});
});
- it('should resolve absolute filepath when in a directory', function() {
+ it('should resolve absolute filepath when in a directory', () => {
return renderTemplate(engine, path.join(dirName, 'hello/test.md'), '{% include "/include.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('Hello World');
});
});
});
+
});
- describe('transform', function() {
+ describe('transform', () => {
function transform(filePath, source) {
expect(filePath).toBeA('string');
expect(source).toBeA('string');
@@ -83,11 +92,16 @@ describe('ConrefsLoader', function() {
return 'test-' + source + '-endtest';
}
- const engine = TemplateEngine({
- loader: new ConrefsLoader(dirName, transform)
+
+ let engine;
+
+ before(() => {
+ engine = new TemplateEngine({
+ loader: new ConrefsLoader(dirName, transform)
+ });
});
- it('should transform included content', function() {
+ it('should transform included content', () => {
return renderTemplate(engine, fileName, '{% include "include.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('test-Hello World-endtest');
@@ -95,4 +109,3 @@ describe('ConrefsLoader', function() {
});
});
});
-
diff --git a/packages/gitbook/src/templating/__tests__/postRender.js b/packages/gitbook/src/templating/__tests__/postRender.js
deleted file mode 100644
index ff5bb61..0000000
--- a/packages/gitbook/src/templating/__tests__/postRender.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const TemplateEngine = require('../../models/templateEngine');
-const TemplateBlock = require('../../models/templateBlock');
-
-const renderTemplate = require('../render');
-const postRender = require('../postRender');
-
-describe('postRender', function() {
- let testPost;
- const engine = TemplateEngine.create({
- blocks: [
- TemplateBlock.create('lower', function(blk) {
- return blk.body.toLowerCase();
- }),
- TemplateBlock.create('prefix', function(blk) {
- return {
- body: '_' + blk.body + '_',
- post() {
- testPost = true;
- }
- };
- })
- ]
- });
-
- it('should correctly replace block', function() {
- return renderTemplate(engine, 'README.md', 'Hello {% lower %}Samy{% endlower %}')
- .then(function(output) {
- expect(output.getContent()).toMatch(/Hello \{\{\-([\S]+)\-\}\}/);
- expect(output.getBlocks().size).toBe(1);
-
- return postRender(engine, output);
- })
- .then(function(result) {
- expect(result).toBe('Hello samy');
- });
- });
-
- it('should correctly replace blocks', function() {
- return renderTemplate(engine, 'README.md', 'Hello {% lower %}Samy{% endlower %}{% prefix %}Pesse{% endprefix %}')
- .then(function(output) {
- expect(output.getContent()).toMatch(/Hello \{\{\-([\S]+)\-\}\}\{\{\-([\S]+)\-\}\}/);
- expect(output.getBlocks().size).toBe(2);
- return postRender(engine, output);
- })
- .then(function(result) {
- expect(result).toBe('Hello samy_Pesse_');
- expect(testPost).toBe(true);
- });
- });
-
-});
diff --git a/packages/gitbook/src/templating/index.js b/packages/gitbook/src/templating/index.js
index bd74aca..5189eac 100644
--- a/packages/gitbook/src/templating/index.js
+++ b/packages/gitbook/src/templating/index.js
@@ -1,10 +1,7 @@
module.exports = {
- render: require('./render'),
- renderFile: require('./renderFile'),
- postRender: require('./postRender'),
- replaceShortcuts: require('./replaceShortcuts'),
-
- ConrefsLoader: require('./conrefsLoader'),
- ThemesLoader: require('./themesLoader')
+ render: require('./render'),
+ renderFile: require('./renderFile'),
+ replaceShortcuts: require('./replaceShortcuts'),
+ ConrefsLoader: require('./conrefsLoader')
};
diff --git a/packages/gitbook/src/templating/listShortcuts.js b/packages/gitbook/src/templating/listShortcuts.js
index 5df88bb..099b709 100644
--- a/packages/gitbook/src/templating/listShortcuts.js
+++ b/packages/gitbook/src/templating/listShortcuts.js
@@ -1,4 +1,4 @@
-const Immutable = require('immutable');
+const { List } = require('immutable');
const parsers = require('../parsers');
/**
@@ -7,13 +7,13 @@ const parsers = require('../parsers');
*
* @param {List<TemplateBlock>} engine
* @param {String} filePath
- * @return {List<TemplateShortcut>}
+ * @return {List<TemplateShortcut>} shortcuts
*/
function listShortcuts(blocks, filePath) {
const parser = parsers.getForFile(filePath);
if (!parser) {
- return Immutable.List();
+ return List();
}
return blocks
diff --git a/packages/gitbook/src/templating/postRender.js b/packages/gitbook/src/templating/postRender.js
deleted file mode 100644
index 7fdfbf4..0000000
--- a/packages/gitbook/src/templating/postRender.js
+++ /dev/null
@@ -1,53 +0,0 @@
-const Promise = require('../utils/promise');
-
-
-/**
- * Replace position markers of blocks by body after processing
- * This is done to avoid that markdown/asciidoc processer parse the block content
- *
- * @param {String} content
- * @return {Object} {blocks: Set, content: String}
- */
-function replaceBlocks(content, blocks) {
- const newContent = content.replace(/\{\{\-\%([\s\S]+?)\%\-\}\}/g, function(match, key) {
- let replacedWith = match;
-
- const block = blocks.get(key);
- if (block) {
- replacedWith = replaceBlocks(block.get('body'), blocks);
- }
-
- return replacedWith;
- });
-
- return newContent;
-}
-
-/**
- * Post render a template:
- * - Execute "post" for blocks
- * - Replace block content
- *
- * @param {TemplateEngine} engine
- * @param {TemplateOutput} content
- * @return {Promise<String>}
- */
-function postRender(engine, output) {
- const content = output.getContent();
- const blocks = output.getBlocks();
-
- const result = replaceBlocks(content, blocks);
-
- return Promise.forEach(blocks, function(block) {
- const post = block.get('post');
-
- if (!post) {
- return;
- }
-
- return post();
- })
- .thenResolve(result);
-}
-
-module.exports = postRender;
diff --git a/packages/gitbook/src/templating/render.js b/packages/gitbook/src/templating/render.js
index 53ed546..945d6dc 100644
--- a/packages/gitbook/src/templating/render.js
+++ b/packages/gitbook/src/templating/render.js
@@ -1,6 +1,5 @@
const Promise = require('../utils/promise');
const timing = require('../utils/timing');
-const TemplateOutput = require('../models/templateOutput');
const replaceShortcuts = require('./replaceShortcuts');
/**
@@ -10,7 +9,7 @@ const replaceShortcuts = require('./replaceShortcuts');
* @param {String} filePath: absolute path for the loader
* @param {String} content
* @param {Object} context (optional)
- * @return {Promise<TemplateOutput>}
+ * @return {Promise<String>}
*/
function renderTemplate(engine, filePath, content, context) {
context = context || {};
@@ -35,9 +34,6 @@ function renderTemplate(engine, filePath, content, context) {
path: filePath
}
)
- .then(function(content) {
- return TemplateOutput.create(content, blocks);
- })
);
}
diff --git a/packages/gitbook/src/templating/themesLoader.js b/packages/gitbook/src/templating/themesLoader.js
deleted file mode 100644
index b1639c5..0000000
--- a/packages/gitbook/src/templating/themesLoader.js
+++ /dev/null
@@ -1,115 +0,0 @@
-const Immutable = require('immutable');
-const nunjucks = require('nunjucks');
-const fs = require('fs');
-const path = require('path');
-
-const PathUtils = require('../utils/path');
-
-
-const ThemesLoader = nunjucks.Loader.extend({
- init(searchPaths) {
- this.searchPaths = Immutable.List(searchPaths)
- .map(path.normalize);
- },
-
- /**
- * Read source of a resolved filepath
- * @param {String}
- * @return {Object}
- */
- getSource(fullpath) {
- if (!fullpath) return null;
-
- fullpath = this.resolve(null, fullpath);
- const templateName = this.getTemplateName(fullpath);
-
- if (!fullpath) {
- return null;
- }
-
- let 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,
- 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() {
- return true;
- },
-
- /**
- * Get original search path containing a template
- * @param {String} filepath
- * @return {String} searchPath
- */
- getSearchPath(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(filepath) {
- const 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(from, to) {
- let 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
- const originalSearchPath = this.getSearchPath(from);
- const 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) {
- const currentIndex = searchPaths.indexOf(originalSearchPath);
- searchPaths = searchPaths.slice(currentIndex + 1);
- }
-
- // Absolute template to resolve in root folder
- const resultFolder = searchPaths.find(function(basePath) {
- const 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;