summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorSamy Pesse <samypesse@gmail.com>2016-10-06 16:29:32 +0200
committerSamy Pesse <samypesse@gmail.com>2016-10-06 16:29:32 +0200
commit1354582c4e0d61c7608965f36b3c27ee3e39dc78 (patch)
tree1f1883ffec98f762d19d6a03c7506676f19822e1 /packages
parent4119917555f827b0bff256a8e34a1deef5f4b87e (diff)
downloadgitbook-1354582c4e0d61c7608965f36b3c27ee3e39dc78.zip
gitbook-1354582c4e0d61c7608965f36b3c27ee3e39dc78.tar.gz
gitbook-1354582c4e0d61c7608965f36b3c27ee3e39dc78.tar.bz2
Generate an url index for generation
Diffstat (limited to 'packages')
-rw-r--r--packages/gitbook-core/src/components/Import.js15
-rw-r--r--packages/gitbook-core/src/components/Link.js42
-rw-r--r--packages/gitbook-core/src/models/File.js14
-rw-r--r--packages/gitbook-core/src/models/SummaryArticle.js35
-rw-r--r--packages/gitbook/src/json/encodeBook.js10
-rw-r--r--packages/gitbook/src/json/encodeReadme.js10
-rw-r--r--packages/gitbook/src/json/encodeSummary.js10
-rw-r--r--packages/gitbook/src/json/encodeSummaryArticle.js22
-rw-r--r--packages/gitbook/src/json/encodeSummaryPart.js10
-rw-r--r--packages/gitbook/src/models/book.js3
-rw-r--r--packages/gitbook/src/models/output.js186
-rw-r--r--packages/gitbook/src/models/page.js103
-rw-r--r--packages/gitbook/src/output/callHook.js16
-rw-r--r--packages/gitbook/src/output/callPageHook.js14
-rw-r--r--packages/gitbook/src/output/createTemplateEngine.js12
-rw-r--r--packages/gitbook/src/output/generateAssets.js12
-rw-r--r--packages/gitbook/src/output/generateBook.js6
-rw-r--r--packages/gitbook/src/output/preparePages.js19
-rw-r--r--packages/gitbook/src/parse/__tests__/parseURIIndexFromPages.js37
-rw-r--r--packages/gitbook/src/parse/parseBook.js30
-rw-r--r--packages/gitbook/src/parse/parsePagesList.js22
-rw-r--r--packages/gitbook/src/parse/parseURIIndexFromPages.js54
22 files changed, 367 insertions, 315 deletions
diff --git a/packages/gitbook-core/src/components/Import.js b/packages/gitbook-core/src/components/Import.js
index 057ef7a..68318b9 100644
--- a/packages/gitbook-core/src/components/Import.js
+++ b/packages/gitbook-core/src/components/Import.js
@@ -2,8 +2,19 @@ const React = require('react');
const Head = require('react-helmet');
const ReactRedux = require('react-redux');
+/**
+ * Resolve a file url to a relative url in current state
+ * @param {String} href
+ * @param {State} state
+ * @return {String}
+ */
+function resolveForCurrentFile(href, state) {
+ const { file } = state;
+ return file.relative(href);
+}
+
const ImportLink = ReactRedux.connect((state, {rel, href}) => {
- href = href; // TODO: resolve using current page
+ href = resolveForCurrentFile(href, state);
return {
link: [
@@ -16,7 +27,7 @@ const ImportLink = ReactRedux.connect((state, {rel, href}) => {
})(Head);
const ImportScript = ReactRedux.connect((state, {type, src}) => {
- src = src; // TODO: resolve using current page
+ src = resolveForCurrentFile(src, state);
return {
script: [
diff --git a/packages/gitbook-core/src/components/Link.js b/packages/gitbook-core/src/components/Link.js
index 8c142ea..f5b9753 100644
--- a/packages/gitbook-core/src/components/Link.js
+++ b/packages/gitbook-core/src/components/Link.js
@@ -4,43 +4,29 @@ const ReactRedux = require('react-redux');
const File = require('../models/File');
const SummaryArticle = require('../models/SummaryArticle');
const SummaryArticleShape = require('../shapes/SummaryArticle');
-const ContextShape = require('../shapes/Context');
+const FileShape = require('../shapes/File');
const Link = React.createClass({
propTypes: {
- children: React.PropTypes.node,
- href: React.PropTypes.string,
- to: React.PropTypes.oneOfType([
+ currentFile: FileShape,
+ children: React.PropTypes.node,
+
+ // Destination of the link
+ to: React.PropTypes.oneOfType([
React.PropTypes.string,
- SummaryArticleShape
+ SummaryArticleShape,
+ FileShape
])
},
- contextTypes: {
- gitbook: ContextShape.isRequired
- },
-
getHref() {
- const { gitbook } = this.context;
- let { to, href } = this.props;
-
- if (href) {
- return href;
- }
-
- if (SummaryArticle.is(to)) {
- return to.toURL(gitbook);
- }
-
- if (typeof to === 'string') {
- to = new File(to);
- }
+ let { currentFile, to } = this.props;
- if (File.is(to)) {
- return to.toURL(gitbook);
+ if (SummaryArticle.is(to) || File.is(to)) {
+ to = to.url;
}
- throw new Error('Invalid format for prop "to"');
+ return currentFile.relative(to);
},
render() {
@@ -50,4 +36,6 @@ const Link = React.createClass({
}
});
-module.exports = ReactRedux.connect()(Link);
+module.exports = ReactRedux.connect(state => {
+ return { currentFile: state.file };
+})(Link);
diff --git a/packages/gitbook-core/src/models/File.js b/packages/gitbook-core/src/models/File.js
index 03032a1..88138c3 100644
--- a/packages/gitbook-core/src/models/File.js
+++ b/packages/gitbook-core/src/models/File.js
@@ -21,16 +21,14 @@ class File extends Record(DEFAULTS) {
}
/**
- * Return url for a file in a GitBook context.
- * @param {Context} context
- * @return {String} url
+ * Returns the relative path from this file to "to"
+ * @param {String} to
+ * @return {String}
*/
- toURL(context) {
- const { file } = context.getState();
-
+ relative(to) {
return path.relative(
- path.dirname(file.path),
- this.path
+ path.dirname(this.path),
+ to
);
}
diff --git a/packages/gitbook-core/src/models/SummaryArticle.js b/packages/gitbook-core/src/models/SummaryArticle.js
index 80ef5ae..0f8ca0d 100644
--- a/packages/gitbook-core/src/models/SummaryArticle.js
+++ b/packages/gitbook-core/src/models/SummaryArticle.js
@@ -1,9 +1,4 @@
-const url = require('url');
-const path = require('path');
const { Record, List } = require('immutable');
-const File = require('./File');
-
-const OUTPUT_EXTENSION = '.html';
const DEFAULTS = {
title: '',
@@ -24,36 +19,6 @@ class SummaryArticle extends Record(DEFAULTS) {
}
/**
- * Return url for a file in a GitBook context.
- * @param {Context} context
- * @return {String} url
- */
- toURL(context) {
- const { readme } = context.getState();
- const fileReadme = readme.file;
- const parts = url.parse(this.ref);
-
- if (parts.protocol) {
- return this.ref;
- }
-
- const file = new File(parts.pathname);
- let filePath = file.toURL(context);
-
- // Change extension and resolve to .html
- if (
- path.basename(filePath, path.extname(filePath)) == 'README' ||
- (fileReadme && filePath == fileReadme.path)
- ) {
- filePath = path.join(path.dirname(filePath), 'index' + OUTPUT_EXTENSION);
- } else {
- filePath = path.basename(filePath, path.extname(filePath)) + OUTPUT_EXTENSION;
- }
-
- return filePath + (parts.hash || '');
- }
-
- /**
* Return true if article is an instance of SummaryArticle
* @param {Mixed} article
* @return {Boolean}
diff --git a/packages/gitbook/src/json/encodeBook.js b/packages/gitbook/src/json/encodeBook.js
index 0b259a9..c5632d2 100644
--- a/packages/gitbook/src/json/encodeBook.js
+++ b/packages/gitbook/src/json/encodeBook.js
@@ -7,11 +7,11 @@ const encodeReadme = require('./encodeReadme');
const encodeLanguages = require('./encodeLanguages');
/**
- Encode a book to JSON
-
- @param {Book}
- @return {Object}
-*/
+ * Encode a book to JSON
+ *
+ * @param {Book}
+ * @return {Object}
+ */
function encodeBookToJson(book) {
const config = book.getConfig();
const language = book.getLanguage();
diff --git a/packages/gitbook/src/json/encodeReadme.js b/packages/gitbook/src/json/encodeReadme.js
index cc71bcb..5fe5a63 100644
--- a/packages/gitbook/src/json/encodeReadme.js
+++ b/packages/gitbook/src/json/encodeReadme.js
@@ -1,11 +1,11 @@
const encodeFile = require('./encodeFile');
/**
- Encode a readme to JSON
-
- @param {Readme}
- @return {Object}
-*/
+ * Encode a readme to JSON
+ *
+ * @param {Readme}
+ * @return {Object}
+ */
function encodeReadme(readme) {
const file = readme.getFile();
diff --git a/packages/gitbook/src/json/encodeSummary.js b/packages/gitbook/src/json/encodeSummary.js
index 9a07da4..0a9dbe7 100644
--- a/packages/gitbook/src/json/encodeSummary.js
+++ b/packages/gitbook/src/json/encodeSummary.js
@@ -2,11 +2,11 @@ const encodeFile = require('./encodeFile');
const encodeSummaryPart = require('./encodeSummaryPart');
/**
- Encode a summary to JSON
-
- @param {Summary}
- @return {Object}
-*/
+ * Encode a summary to JSON
+ *
+ * @param {Summary}
+ * @return {Object}
+ */
function encodeSummary(summary) {
const file = summary.getFile();
const parts = summary.getParts();
diff --git a/packages/gitbook/src/json/encodeSummaryArticle.js b/packages/gitbook/src/json/encodeSummaryArticle.js
index 0b9461c..b6d7d9f 100644
--- a/packages/gitbook/src/json/encodeSummaryArticle.js
+++ b/packages/gitbook/src/json/encodeSummaryArticle.js
@@ -1,10 +1,10 @@
/**
- Encode a SummaryArticle to JSON
-
- @param {SummaryArticle}
- @return {Object}
-*/
+ * Encode a SummaryArticle to JSON
+ *
+ * @param {SummaryArticle}
+ * @return {Object}
+ */
function encodeSummaryArticle(article, recursive) {
let articles = undefined;
if (recursive !== false) {
@@ -14,13 +14,13 @@ function encodeSummaryArticle(article, recursive) {
}
return {
- title: article.getTitle(),
- level: article.getLevel(),
- depth: article.getDepth(),
+ title: article.getTitle(),
+ level: article.getLevel(),
+ depth: article.getDepth(),
anchor: article.getAnchor(),
- url: article.getUrl(),
- path: article.getPath(),
- ref: article.getRef(),
+ url: article.getUrl(),
+ path: article.getPath(),
+ ref: article.getRef(),
articles
};
}
diff --git a/packages/gitbook/src/json/encodeSummaryPart.js b/packages/gitbook/src/json/encodeSummaryPart.js
index eb16719..9ff3583 100644
--- a/packages/gitbook/src/json/encodeSummaryPart.js
+++ b/packages/gitbook/src/json/encodeSummaryPart.js
@@ -1,11 +1,11 @@
const encodeSummaryArticle = require('./encodeSummaryArticle');
/**
- Encode a SummaryPart to JSON
-
- @param {SummaryPart}
- @return {Object}
-*/
+ * Encode a SummaryPart to JSON
+ *
+ * @param {SummaryPart}
+ * @return {Object}
+ */
function encodeSummaryPart(part) {
return {
title: part.getTitle(),
diff --git a/packages/gitbook/src/models/book.js b/packages/gitbook/src/models/book.js
index c96843b..4668154 100644
--- a/packages/gitbook/src/models/book.js
+++ b/packages/gitbook/src/models/book.js
@@ -10,7 +10,6 @@ const Summary = require('./summary');
const Glossary = require('./glossary');
const Languages = require('./languages');
const Ignore = require('./ignore');
-const URIIndex = require('./uriIndex');
const DEFAULTS = {
// Logger for output message
@@ -25,8 +24,6 @@ const DEFAULTS = {
summary: new Summary(),
glossary: new Glossary(),
languages: new Languages(),
- // Index of urls
- urls: new URIIndex(),
// ID of the language for language books
language: String(),
// List of children, if multilingual (String -> Book)
diff --git a/packages/gitbook/src/models/output.js b/packages/gitbook/src/models/output.js
index ae68f4c..e4870ba 100644
--- a/packages/gitbook/src/models/output.js
+++ b/packages/gitbook/src/models/output.js
@@ -1,107 +1,105 @@
-const Immutable = require('immutable');
+const { Record, OrderedMap, Map, List } = require('immutable');
-const Book = require('./book');
const LocationUtils = require('../utils/location');
+const Book = require('./book');
+const URIIndex = require('./uriIndex');
-const Output = Immutable.Record({
- book: new Book(),
-
+const DEFAULTS = {
+ book: new Book(),
// Name of the generator being used
- generator: String(),
-
+ generator: String(),
// Map of plugins to use (String -> Plugin)
- plugins: Immutable.OrderedMap(),
-
+ plugins: OrderedMap(),
// Map pages to generation (String -> Page)
- pages: Immutable.OrderedMap(),
-
+ pages: OrderedMap(),
// List assets (String)
- assets: Immutable.List(),
-
+ assets: List(),
// Option for the generation
- options: Immutable.Map(),
-
+ options: Map(),
// Internal state for the generation
- state: Immutable.Map()
-});
-
-Output.prototype.getBook = function() {
- return this.get('book');
-};
-
-Output.prototype.getGenerator = function() {
- return this.get('generator');
-};
-
-Output.prototype.getPlugins = function() {
- return this.get('plugins');
-};
-
-Output.prototype.getPages = function() {
- return this.get('pages');
-};
-
-Output.prototype.getOptions = function() {
- return this.get('options');
-};
-
-Output.prototype.getAssets = function() {
- return this.get('assets');
-};
-
-Output.prototype.getState = function() {
- return this.get('state');
-};
-
-/**
- Return a page byt its file path
-
- @param {String} filePath
- @return {Page|undefined}
-*/
-Output.prototype.getPage = function(filePath) {
- filePath = LocationUtils.normalize(filePath);
-
- const pages = this.getPages();
- return pages.get(filePath);
-};
-
-/**
- Get root folder for output
-
- @return {String}
-*/
-Output.prototype.getRoot = function() {
- return this.getOptions().get('root');
+ state: Map(),
+ // Index of urls
+ urls: new URIIndex()
};
-/**
- Update state of output
-
- @param {Map} newState
- @return {Output}
-*/
-Output.prototype.setState = function(newState) {
- return this.set('state', newState);
-};
-
-/**
- Update options
-
- @param {Map} newOptions
- @return {Output}
-*/
-Output.prototype.setOptions = function(newOptions) {
- return this.set('options', newOptions);
-};
-
-/**
- Return logegr for this output (same as book)
-
- @return {Logger}
-*/
-Output.prototype.getLogger = function() {
- return this.getBook().getLogger();
-};
+class Output extends Record(DEFAULTS) {
+ getBook() {
+ return this.get('book');
+ }
+
+ getGenerator() {
+ return this.get('generator');
+ }
+
+ getPlugins() {
+ return this.get('plugins');
+ }
+
+ getPages() {
+ return this.get('pages');
+ }
+
+ getOptions() {
+ return this.get('options');
+ }
+
+ getAssets() {
+ return this.get('assets');
+ }
+
+ getState() {
+ return this.get('state');
+ }
+
+ /**
+ * Return a page byt its file path
+ *
+ * @param {String} filePath
+ * @return {Page|undefined}
+ */
+ getPage(filePath) {
+ filePath = LocationUtils.normalize(filePath);
+
+ const pages = this.getPages();
+ return pages.get(filePath);
+ }
+
+ /**
+ * Get root folder for output.
+ * @return {String}
+ */
+ getRoot() {
+ return this.getOptions().get('root');
+ }
+
+ /**
+ * Update state of output
+ *
+ * @param {Map} newState
+ * @return {Output}
+ */
+ setState(newState) {
+ return this.set('state', newState);
+ }
+
+ /**
+ * Update options
+ *
+ * @param {Map} newOptions
+ * @return {Output}
+ */
+ setOptions(newOptions) {
+ return this.set('options', newOptions);
+ }
+
+ /**
+ * Return logegr for this output (same as book)
+ *
+ * @return {Logger}
+ */
+ getLogger() {
+ return this.getBook().getLogger();
+ }
+}
module.exports = Output;
diff --git a/packages/gitbook/src/models/page.js b/packages/gitbook/src/models/page.js
index dd60298..e2ab977 100644
--- a/packages/gitbook/src/models/page.js
+++ b/packages/gitbook/src/models/page.js
@@ -1,70 +1,69 @@
-const Immutable = require('immutable');
+const { Record, Map } = require('immutable');
const yaml = require('js-yaml');
const File = require('./file');
-const Page = Immutable.Record({
- file: File(),
-
+const DEFAULTS = {
+ file: File(),
// Attributes extracted from the YAML header
- attributes: Immutable.Map(),
-
+ attributes: Map(),
// Content of the page
- content: String(),
-
+ content: String(),
// Direction of the text
- dir: String('ltr')
-});
-
-Page.prototype.getFile = function() {
- return this.get('file');
-};
-
-Page.prototype.getAttributes = function() {
- return this.get('attributes');
+ dir: String('ltr')
};
-Page.prototype.getContent = function() {
- return this.get('content');
-};
+class Page extends Record(DEFAULTS) {
+ getFile() {
+ return this.get('file');
+ }
-Page.prototype.getDir = function() {
- return this.get('dir');
-};
+ getAttributes() {
+ return this.get('attributes');
+ }
-/**
- * Return page as text
- * @return {String}
-*/
-Page.prototype.toText = function() {
- const attrs = this.getAttributes();
- const content = this.getContent();
+ getContent() {
+ return this.get('content');
+ }
- if (attrs.size === 0) {
- return content;
+ getDir() {
+ return this.get('dir');
}
- const frontMatter = '---\n' + yaml.safeDump(attrs.toJS(), { skipInvalid: true }) + '---\n\n';
- return (frontMatter + content);
-};
+ /**
+ * Return page as text
+ * @return {String}
+ */
+ toText() {
+ const attrs = this.getAttributes();
+ const content = this.getContent();
-/**
- * Return path of the page
- * @return {String}
-*/
-Page.prototype.getPath = function() {
- return this.getFile().getPath();
-};
+ if (attrs.size === 0) {
+ return content;
+ }
-/**
- * Create a page for a file
- * @param {File} file
- * @return {Page}
-*/
-Page.createForFile = function(file) {
- return new Page({
- file
- });
-};
+ const frontMatter = '---\n' + yaml.safeDump(attrs.toJS(), { skipInvalid: true }) + '---\n\n';
+ return (frontMatter + content);
+ }
+
+ /**
+ * Return path of the page
+ * @return {String}
+ */
+ getPath() {
+ return this.getFile().getPath();
+ }
+
+ /**
+ * Create a page for a file
+ * @param {File} file
+ * @return {Page}
+ */
+ static createForFile(file) {
+ return new Page({
+ file
+ });
+ }
+}
module.exports = Page;
diff --git a/packages/gitbook/src/output/callHook.js b/packages/gitbook/src/output/callHook.js
index 2180102..34c16ab 100644
--- a/packages/gitbook/src/output/callHook.js
+++ b/packages/gitbook/src/output/callHook.js
@@ -11,14 +11,14 @@ function defaultHandleResult(output, result) {
}
/**
- Call a "global" hook for an output
-
- @param {String} name
- @param {Function(Output) -> Mixed} getArgument
- @param {Function(Output, result) -> Output} handleResult
- @param {Output} output
- @return {Promise<Output>}
-*/
+ * Call a "global" hook for an output. Hooks are functions exported by plugins.
+ *
+ * @param {String} name
+ * @param {Function(Output) -> Mixed} getArgument
+ * @param {Function(Output, result) -> Output} handleResult
+ * @param {Output} output
+ * @return {Promise<Output>}
+ */
function callHook(name, getArgument, handleResult, output) {
getArgument = getArgument || defaultGetArgument;
handleResult = handleResult || defaultHandleResult;
diff --git a/packages/gitbook/src/output/callPageHook.js b/packages/gitbook/src/output/callPageHook.js
index af249c9..0c7adfa 100644
--- a/packages/gitbook/src/output/callPageHook.js
+++ b/packages/gitbook/src/output/callPageHook.js
@@ -2,13 +2,13 @@ const Api = require('../api');
const callHook = require('./callHook');
/**
- Call a hook for a specific page
-
- @param {String} name
- @param {Output} output
- @param {Page} page
- @return {Promise<Page>}
-*/
+ * Call a hook for a specific page.
+ *
+ * @param {String} name
+ * @param {Output} output
+ * @param {Page} page
+ * @return {Promise<Page>}
+ */
function callPageHook(name, output, page) {
return callHook(
name,
diff --git a/packages/gitbook/src/output/createTemplateEngine.js b/packages/gitbook/src/output/createTemplateEngine.js
index 03e7d84..93b1c58 100644
--- a/packages/gitbook/src/output/createTemplateEngine.js
+++ b/packages/gitbook/src/output/createTemplateEngine.js
@@ -8,12 +8,12 @@ const defaultBlocks = require('../constants/defaultBlocks');
const defaultFilters = require('../constants/defaultFilters');
/**
- Create template engine for an output.
- It adds default filters/blocks, then add the ones from plugins
-
- @param {Output} output
- @return {TemplateEngine}
-*/
+ * Create template engine for an output.
+ * It adds default filters/blocks, then add the ones from plugins
+ *
+ * @param {Output} output
+ * @return {TemplateEngine}
+ */
function createTemplateEngine(output) {
const plugins = output.getPlugins();
const book = output.getBook();
diff --git a/packages/gitbook/src/output/generateAssets.js b/packages/gitbook/src/output/generateAssets.js
index 2129553..f926492 100644
--- a/packages/gitbook/src/output/generateAssets.js
+++ b/packages/gitbook/src/output/generateAssets.js
@@ -1,12 +1,12 @@
const Promise = require('../utils/promise');
/**
- Output all assets using a generator
-
- @param {Generator} generator
- @param {Output} output
- @return {Promise<Output>}
-*/
+ * Output all assets using a generator
+ *
+ * @param {Generator} generator
+ * @param {Output} output
+ * @return {Promise<Output>}
+ */
function generateAssets(generator, output) {
const assets = output.getAssets();
const logger = output.getLogger();
diff --git a/packages/gitbook/src/output/generateBook.js b/packages/gitbook/src/output/generateBook.js
index ea8c78e..e27d3ce 100644
--- a/packages/gitbook/src/output/generateBook.js
+++ b/packages/gitbook/src/output/generateBook.js
@@ -167,7 +167,7 @@ function generateBook(generator, book, options) {
)
// Cleanup output folder
- .then(function(output) {
+ .then((output) => {
const logger = output.getLogger();
const rootFolder = output.getRoot();
@@ -176,10 +176,10 @@ function generateBook(generator, book, options) {
.thenResolve(output);
})
- .then(processOutput.bind(null, generator))
+ .then(output => processOutput(generator, output))
// Log duration and end message
- .then(function(output) {
+ .then((output) => {
const logger = output.getLogger();
const end = Date.now();
const duration = (end - start) / 1000;
diff --git a/packages/gitbook/src/output/preparePages.js b/packages/gitbook/src/output/preparePages.js
index e65367e..ba8519f 100644
--- a/packages/gitbook/src/output/preparePages.js
+++ b/packages/gitbook/src/output/preparePages.js
@@ -1,12 +1,13 @@
const Parse = require('../parse');
const Promise = require('../utils/promise');
+const parseURIIndexFromPages = require('../parse/parseURIIndexFromPages');
/**
- List and prepare all pages
-
- @param {Output}
- @return {Promise<Output>}
-*/
+ * List and parse all pages, then create the urls mapping.
+ *
+ * @param {Output}
+ * @return {Promise<Output>}
+ */
function preparePages(output) {
const book = output.getBook();
const logger = book.getLogger();
@@ -16,10 +17,14 @@ function preparePages(output) {
}
return Parse.parsePagesList(book)
- .then(function(pages) {
+ .then((pages) => {
logger.info.ln('found', pages.size, 'pages');
+ const urls = parseURIIndexFromPages(pages);
- return output.set('pages', pages);
+ return output.merge({
+ pages,
+ urls
+ });
});
}
diff --git a/packages/gitbook/src/parse/__tests__/parseURIIndexFromPages.js b/packages/gitbook/src/parse/__tests__/parseURIIndexFromPages.js
new file mode 100644
index 0000000..e3b9b55
--- /dev/null
+++ b/packages/gitbook/src/parse/__tests__/parseURIIndexFromPages.js
@@ -0,0 +1,37 @@
+const { OrderedMap } = require('immutable');
+
+const parseURIIndexFromPages = require('../parseURIIndexFromPages');
+const Page = require('../../models/page');
+
+describe.only('parseURIIndexFromPages', () => {
+
+ it('should map file to html', () => {
+ const pages = OrderedMap({
+ 'page.md': new Page()
+ });
+ const urls = parseURIIndexFromPages(pages);
+
+ 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/');
+ });
+
+});
diff --git a/packages/gitbook/src/parse/parseBook.js b/packages/gitbook/src/parse/parseBook.js
index 85f4519..e5c1784 100644
--- a/packages/gitbook/src/parse/parseBook.js
+++ b/packages/gitbook/src/parse/parseBook.js
@@ -10,11 +10,11 @@ const parseReadme = require('./parseReadme');
const parseLanguages = require('./parseLanguages');
/**
- Parse content of a book
-
- @param {Book} book
- @return {Promise<Book>}
-*/
+ * Parse content of a book
+ *
+ * @param {Book} book
+ * @return {Promise<Book>}
+ */
function parseBookContent(book) {
return Promise(book)
.then(parseReadme)
@@ -23,11 +23,11 @@ function parseBookContent(book) {
}
/**
- Parse a multilingual book
-
- @param {Book} book
- @return {Promise<Book>}
-*/
+ * Parse a multilingual book
+ *
+ * @param {Book} book
+ * @return {Promise<Book>}
+ */
function parseMultilingualBook(book) {
const languages = book.getLanguages();
const langList = languages.getList();
@@ -52,11 +52,11 @@ function parseMultilingualBook(book) {
/**
- Parse a whole book from a filesystem
-
- @param {Book} book
- @return {Promise<Book>}
-*/
+ * Parse a whole book from a filesystem
+ *
+ * @param {Book} book
+ * @return {Promise<Book>}
+ */
function parseBook(book) {
return timing.measure(
'parse.book',
diff --git a/packages/gitbook/src/parse/parsePagesList.js b/packages/gitbook/src/parse/parsePagesList.js
index 2383dbf..89a1a4f 100644
--- a/packages/gitbook/src/parse/parsePagesList.js
+++ b/packages/gitbook/src/parse/parsePagesList.js
@@ -7,12 +7,12 @@ const parsePage = require('./parsePage');
/**
- Parse a page from a path
-
- @param {Book} book
- @param {String} filePath
- @return {Page?}
-*/
+ * Parse a page from a path
+ *
+ * @param {Book} book
+ * @param {String} filePath
+ * @return {Page?}
+ */
function parseFilePage(book, filePath) {
const fs = book.getContentFS();
@@ -36,11 +36,11 @@ function parseFilePage(book, filePath) {
/**
- Parse all pages from a book as an OrderedMap
-
- @param {Book} book
- @return {Promise<OrderedMap<Page>>}
-*/
+ * Parse all pages from a book as an OrderedMap
+ *
+ * @param {Book} book
+ * @return {Promise<OrderedMap<Page>>}
+ */
function parsePagesList(book) {
const summary = book.getSummary();
const glossary = book.getGlossary();
diff --git a/packages/gitbook/src/parse/parseURIIndexFromPages.js b/packages/gitbook/src/parse/parseURIIndexFromPages.js
new file mode 100644
index 0000000..d5f745e
--- /dev/null
+++ b/packages/gitbook/src/parse/parseURIIndexFromPages.js
@@ -0,0 +1,54 @@
+const path = require('path');
+const PathUtils = require('../utils/path');
+const LocationUtils = require('../utils/location');
+const URIIndex = require('../models/uriIndex');
+
+const OUTPUT_EXTENSION = '.html';
+
+/**
+ * Convert a filePath (absolute) to an url (without hostname).
+ * It returns an absolute path.
+ *
+ * "README.md" -> "/"
+ * "test/hello.md" -> "test/hello.html"
+ * "test/README.md" -> "test/"
+ *
+ * @param {Output} output
+ * @param {String} filePath
+ * @return {String}
+ */
+function fileToURL(filePath, directoryIndex) {
+ if (
+ path.basename(filePath, path.extname(filePath)) == 'README'
+ ) {
+ filePath = path.join(path.dirname(filePath), 'index' + OUTPUT_EXTENSION);
+ } else {
+ filePath = PathUtils.setExtension(filePath, OUTPUT_EXTENSION);
+ }
+
+ if (directoryIndex && path.basename(filePath) == 'index.html') {
+ filePath = path.dirname(filePath) + '/';
+ }
+
+ return LocationUtils.normalize(filePath);
+}
+
+/**
+ * Parse a set of pages into an URIIndex.
+ * Each pages is added as an entry in the index.
+ *
+ * @param {OrderedMap<Page>} pages
+ * @param {Boolean} options.directoryIndex: should we use "index.html" or "/"
+ * @return {URIIndex} index
+ */
+function parseURIIndexFromPages(pages, options) {
+ options = options || {};
+ if (typeof options.directoryIndex === 'undefined') {
+ options.directoryIndex = true;
+ }
+
+ const urls = pages.map((page, filePath) => fileToURL(filePath, options.directoryIndex));
+ return new URIIndex(urls);
+}
+
+module.exports = parseURIIndexFromPages;