diff options
author | Soreine <nicolas@gitbook.com> | 2017-03-09 16:10:02 +0100 |
---|---|---|
committer | Soreine <nicolas@gitbook.com> | 2017-03-09 16:10:02 +0100 |
commit | 8d6e31bf6089d207302fecd5fa71b8d9889413cd (patch) | |
tree | 73bc57058d38e0a251a8ecb4d57fb5ab7fc4b1bd | |
parent | 621f0ef0016bda3f65fe4bf01a339ec693cee3ef (diff) | |
download | gitbook-8d6e31bf6089d207302fecd5fa71b8d9889413cd.zip gitbook-8d6e31bf6089d207302fecd5fa71b8d9889413cd.tar.gz gitbook-8d6e31bf6089d207302fecd5fa71b8d9889413cd.tar.bz2 |
gitbook: Add modifier `movePath`
-rw-r--r-- | packages/gitbook/src/modifiers/summary/__tests__/movePath.js | 161 | ||||
-rw-r--r-- | packages/gitbook/src/modifiers/summary/index.js | 1 | ||||
-rw-r--r-- | packages/gitbook/src/modifiers/summary/movePath.js | 55 |
3 files changed, 217 insertions, 0 deletions
diff --git a/packages/gitbook/src/modifiers/summary/__tests__/movePath.js b/packages/gitbook/src/modifiers/summary/__tests__/movePath.js new file mode 100644 index 0000000..ac2911c --- /dev/null +++ b/packages/gitbook/src/modifiers/summary/__tests__/movePath.js @@ -0,0 +1,161 @@ +const expect = require('expect'); +const Summary = require('../../../models/summary'); + +describe('movePath', () => { + const movePath = require('../movePath'); + + const summary = Summary.createFromParts([ + { + articles: [ + { + title: 'Intro', + path: 'README.md' + } + ] + }, + { + title: 'Part', + articles: [ + { + title: '1', + path: '' + }, + { + title: '2', + path: '2/README.md', + articles: [ + { + title: '2a', + path: '2/1.md' + }, + { + title: '2b', + path: '2/1.md#anchor' + } + ] + } + ] + } + ]); + + it('should move a single article', () => { + const newSummary = movePath(summary, 'README.md', 'README2.md'); + expectParts(newSummary, [ + { + articles: [ + { + title: 'Intro', + path: 'README2.md' + } + ] + }, + { + title: 'Part', + articles: [ + { + title: '1', + path: '' + }, + { + title: '2', + path: '2/README.md', + articles: [ + { + title: '2a', + path: '2/1.md' + }, + { + title: '2b', + path: '2/1.md#anchor' + } + ] + } + ] + } + ]); + }); + + it('should handle anchors', () => { + const newSummary = movePath(summary, '2/1.md', '2/2.md'); + expectParts(newSummary, [ + { + articles: [ + { + title: 'Intro', + path: 'README.md' + } + ] + }, + { + title: 'Part', + articles: [ + { + title: '1', + path: '' + }, + { + title: '2', + path: '2/README.md', + articles: [ + { + title: '2a', + path: '2/2.md' + }, + { + title: '2b', + path: '2/2.md#anchor' + } + ] + } + ] + } + ]); + }); + + it('should handle dirs', () => { + const newSummary = movePath(summary, '2/', '3/'); + expectParts(newSummary, [ + { + articles: [ + { + title: 'Intro', + path: 'README.md' + } + ] + }, + { + title: 'Part', + articles: [ + { + title: '1', + path: '' + }, + { + title: '2', + path: '3/README.md', + articles: [ + { + title: '2a', + path: '3/1.md' + }, + { + title: '2b', + path: '3/1.md#anchor' + } + ] + } + ] + } + ]); + }); +}); + +function expectParts(summary, expectedParts) { + const expectedSummary = Summary.createFromParts(expectedParts); + expect( + summary.toJS().parts + ).toEqual( + expectedSummary.toJS().parts + ); +} + diff --git a/packages/gitbook/src/modifiers/summary/index.js b/packages/gitbook/src/modifiers/summary/index.js index 28ec625..ffd9188 100644 --- a/packages/gitbook/src/modifiers/summary/index.js +++ b/packages/gitbook/src/modifiers/summary/index.js @@ -10,6 +10,7 @@ module.exports = { editArticleTitle: require('./editArticleTitle'), editArticleRef: require('./editArticleRef'), deleteByPath: require('./deleteByPath'), + movePath: require('./movePath'), // Parts insertPart: require('./insertPart'), removePart: require('./removePart'), diff --git a/packages/gitbook/src/modifiers/summary/movePath.js b/packages/gitbook/src/modifiers/summary/movePath.js new file mode 100644 index 0000000..e864212 --- /dev/null +++ b/packages/gitbook/src/modifiers/summary/movePath.js @@ -0,0 +1,55 @@ +const PathUtils = require('../../utils/path'); + +/** + * Update refs of all articles matching the given path, to the new path. + * Refs are updated as if you were moving a file or a directory. + * @param {Summary} summary + * @param {String} path Can be a file path, or directory path (end with '/') + * @param {String} newPath + * @return {Summary} + */ +function movePath(summary, path, newPath) { + const parts = summary.getParts() + .map((part) => { + const articles = moveArticlesPath(part.getArticles(), path, newPath); + return part.merge({ articles }); + }); + + return summary.merge({ parts }); +} + +/** + * Same as `movePath` but for a list of articles. + * + * @param {List<Article>} articles + * @param {String} path + * @param {String} newPath + * @return {List<Article} + */ +function moveArticlesPath(articles, path, newPath) { + return articles + .map(article => article.merge({ + ref: moveRef(article, path, newPath), + articles: moveArticlesPath(article.articles, path, newPath) + })); +} + +/** + * @param {Article} article + * @param {String} path File path or dir path + * @param {String} newPath + * @return {String} The updated ref for this article (unchanged if not matching `path`). + */ +function moveRef(article, path, newPath) { + const articlePath = article.getPath(); + if (!articlePath || !PathUtils.isInside(articlePath, path)) { + // Nothing to update + return article.getRef(); + } + + // else move it + const anchor = article.getAnchor() || '' ; + return newPath + articlePath.substring(path.length) + anchor; +} + +module.exports = movePath; |