summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSoreine <nicolas@gitbook.com>2017-03-09 16:10:02 +0100
committerSoreine <nicolas@gitbook.com>2017-03-09 16:10:02 +0100
commit8d6e31bf6089d207302fecd5fa71b8d9889413cd (patch)
tree73bc57058d38e0a251a8ecb4d57fb5ab7fc4b1bd
parent621f0ef0016bda3f65fe4bf01a339ec693cee3ef (diff)
downloadgitbook-8d6e31bf6089d207302fecd5fa71b8d9889413cd.zip
gitbook-8d6e31bf6089d207302fecd5fa71b8d9889413cd.tar.gz
gitbook-8d6e31bf6089d207302fecd5fa71b8d9889413cd.tar.bz2
gitbook: Add modifier `movePath`
-rw-r--r--packages/gitbook/src/modifiers/summary/__tests__/movePath.js161
-rw-r--r--packages/gitbook/src/modifiers/summary/index.js1
-rw-r--r--packages/gitbook/src/modifiers/summary/movePath.js55
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;