Skip to content

Commit 693171c

Browse files
author
Soreine
committed
Adds move and remove article modifier.
1 parent 6b17d08 commit 693171c

File tree

6 files changed

+158
-29
lines changed

6 files changed

+158
-29
lines changed

lib/models/summary.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,27 @@ Summary.prototype.getPrevArticle = function(current) {
129129
return prev;
130130
};
131131

132+
/**
133+
Return the parent article, or parent part of an article
134+
135+
@param {String|Article} current
136+
@return {Article|Part|Null}
137+
*/
138+
Summary.prototype.getParent = function (level) {
139+
// Coerce to level
140+
level = is.string(level)? level : level.getLevel();
141+
142+
// Get parent level
143+
var parentLevel = getParentLevel(level);
144+
if (!parentLevel) {
145+
return null;
146+
}
147+
148+
// Get parent of the position
149+
var parentArticle = this.getByLevel(parentLevel);
150+
return parentArticle || null;
151+
};
152+
132153
/**
133154
Render summary as text
134155
@@ -188,4 +209,15 @@ Summary.createFromParts = function createFromParts(file, parts) {
188209
});
189210
};
190211

212+
/**
213+
Returns parent level of a level
214+
215+
@param {String} level
216+
@return {String}
217+
*/
218+
function getParentLevel(level) {
219+
var parts = level.split('.');
220+
return parts.slice(0, -1).join('.');
221+
}
222+
191223
module.exports = Summary;

lib/modifiers/summary/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
21
module.exports = {
32
insertArticle: require('./insertArticle'),
3+
moveArticle: require('./moveArticle'),
4+
removeArticle: require('./removeArticle'),
45
unshiftArticle: require('./unshiftArticle'),
56

67
editPartTitle: require('./editPartTitle'),

lib/modifiers/summary/insertArticle.js

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,6 @@ var SummaryArticle = require('../../models/summaryArticle');
33
var editArticle = require('./editArticle');
44
var indexArticleLevels = require('./indexArticleLevels');
55

6-
7-
/**
8-
Get level of parent of an article
9-
10-
@param {String} level
11-
@return {String}
12-
*/
13-
function getParentLevel(level) {
14-
var parts = level.split('.');
15-
return parts.slice(0, -1).join('.');
16-
}
17-
186
/**
197
Insert an article in a summary at a specific position
208
@@ -27,21 +15,13 @@ function insertArticle(summary, level, article) {
2715
article = SummaryArticle(article);
2816
level = is.string(level)? level : level.getLevel();
2917

30-
var parentLevel = getParentLevel(level);
31-
32-
if (!parentLevel) {
33-
// todo: insert new part
34-
return summary;
35-
}
36-
37-
// Get parent of the position
38-
var parentArticle = summary.getByLevel(parentLevel);
39-
if (!parentLevel) {
18+
var parent = summary.getParent(level);
19+
if (!parent) {
4020
return summary;
4121
}
4222

4323
// Find the index to insert at
44-
var articles = parentArticle.getArticles();
24+
var articles = parent.getArticles();
4525
var index = articles.findIndex(function(art) {
4626
return art.getLevel() === level;
4727
});
@@ -53,11 +33,10 @@ function insertArticle(summary, level, article) {
5333
articles = articles.insert(index, article);
5434

5535
// Reindex the level from here
56-
parentArticle = parentArticle.set('articles', articles);
57-
parentArticle = indexArticleLevels(parentArticle);
58-
59-
return editArticle(summary, parentLevel, parentArticle);
36+
parent = parent.set('articles', articles);
37+
parent = indexArticleLevels(parent);
6038

39+
return editArticle(summary, parent.getLevel(), parent);
6140
}
6241

6342
module.exports = insertArticle;
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
var is = require('is');
2+
var removeArticle = require('./removeArticle');
3+
var insertArticle = require('./insertArticle');
4+
5+
/**
6+
Remove an article from a level, and insert it after another.
7+
8+
@param {Summary} summary
9+
@param {String|SummaryArticle} from: level to remove
10+
@param {String|SummaryArticle} to: level to insert after
11+
@return {Summary}
12+
*/
13+
function moveArticle(summary, from, to) {
14+
// Coerce to level
15+
var fromLevel = is.string(from)? from : from.getLevel();
16+
var toLevel = is.string(to)? to : to.getLevel();
17+
18+
var article = summary.getByLevel(fromLevel);
19+
20+
// Remove
21+
var removed = removeArticle(summary, from);
22+
23+
// Adjust toLevel if removing impacted it
24+
toLevel = arrayToLevel(
25+
shiftLevel(levelToArray(fromLevel),
26+
levelToArray(toLevel)));
27+
// Re-insert
28+
return insertArticle(removed, to, article);
29+
}
30+
31+
/**
32+
@param {Array<Number>} removedLevel
33+
@param {Array<Number>} level The level to udpate
34+
@return {Array<Number>}
35+
*/
36+
function shiftLevel(removedLevel, level) {
37+
if (level.length === 0) {
38+
// `removedLevel` is under level, so no effect
39+
return level;
40+
} else if (removedLevel.length === 0) {
41+
// Either `level` is a child of `removedLevel`... or they are equal
42+
// This is undefined behavior.
43+
return level;
44+
}
45+
46+
var removedRoot = removedLevel[0];
47+
var root = level[0];
48+
var removedRest = removedLevel.unshift();
49+
var rest = level.unshift();
50+
51+
if (removedRoot < root) {
52+
// It will shift levels at this point. The rest is unchanged.
53+
return Array.prototype.concat(root - 1, rest);
54+
} else if (removedRoot === root) {
55+
// Look deeper
56+
return Array.prototype.concat(root, shiftLevel(removedRest, rest));
57+
} else {
58+
// No impact
59+
return level;
60+
}
61+
}
62+
63+
/**
64+
@param {String}
65+
@return {Array<Number>}
66+
*/
67+
function levelToArray(l) {
68+
return l.split('.').map(function (char) {
69+
return parseInt(char, 10);
70+
});
71+
}
72+
73+
/**
74+
@param {Array<Number>}
75+
@return {String}
76+
*/
77+
function arrayToLevel(a) {
78+
return a.join('.');
79+
}
80+
81+
module.exports = moveArticle;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
var is = require('is');
2+
var editArticle = require('./editArticle');
3+
var indexArticleLevels = require('./indexArticleLevels');
4+
5+
/**
6+
Remove an article from a level.
7+
8+
@param {Summary} summary
9+
@param {String|SummaryArticle} level: level to remove
10+
@return {Summary}
11+
*/
12+
function removeArticle(summary, level) {
13+
// Coerce to level
14+
level = is.string(level)? level : level.getLevel();
15+
16+
var parent = summary.getParent(summary, level);
17+
18+
// Find the index to remove
19+
var index = articles.findIndex(function(art) {
20+
return art.getLevel() === level;
21+
});
22+
if (!index) {
23+
return summary;
24+
}
25+
26+
// Remove from children
27+
var articles = parent.getArticles().remove(index);
28+
parent = parent.set('articles', articles);
29+
30+
// Reindex the level from here
31+
parent = indexArticleLevels(parent);
32+
33+
return editArticle(summary, parent.getLevel(), parent);
34+
}
35+
36+
module.exports = removeArticle;

lib/modifiers/summary/unshiftArticle.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ var SummaryPart = require('../../models/summaryPart');
44
var indexLevels = require('./indexLevels');
55

66
/**
7-
Insert an article at the
7+
Insert an article at the beginning of summary
88
99
@param {Summary} summary
1010
@param {Article} article

0 commit comments

Comments
 (0)