-
Notifications
You must be signed in to change notification settings - Fork 0
/
stack.js
145 lines (132 loc) · 4.15 KB
/
stack.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
The stack data structure stores our current position in the indentation hierarchy
*/
function inChrome() {
try {
return !module;
} catch (e) {
return true;
}
}
if (!inChrome()) {
var _ = require('./lodash.core.js');
}
var bulletExpression = /^((V?I{1,3}V?\.)|([A-Z]\.)|(\d+\.)|([a-z]\.)|(\(\d\))|(\([a-z]\))|(\(v?i{1,3}v?\)))/;
var Stack = function () {
this.currentElement = {children: []};
this.root = this.currentElement;
this.stack = [];
this.currentLevel = 0;
this.modifyStack = function (newBullet, headerId, text) {
var newLevel = this.bulletLevel(newBullet);
var newElement = {
children: [], bullet: newBullet, headerId: headerId,
text: text
};
if (newLevel > this.currentLevel) {
//More than one level of indent-this probably means an error in their Document
if (newLevel > (this.currentLevel + 1)) {
for (var i = 0; i < (newLevel - this.currentLevel - 1); i++) {
var tempElement = {children: [], bullet: '(Placeholder)', text: 'placeholder',
parent: this.currentElement}
this.currentElement.children.push(tempElement);
this.currentElement = tempElement;
}
}
//This bullet represents a further indentation
newElement.parent = this.currentElement;
this.currentElement.children.push(newElement);
this.currentElement = newElement;
this.currentLevel = newLevel;
}
else if (newLevel == this.currentLevel) {
//This bullet represents a bullet at the same level of indentation
newElement.parent = this.currentElement.parent;
//Special case: we are adding a top level bullet
if (this.currentElement.parent == undefined) {
newElement.parent = this.currentElement;
this.currentElement.children.push(newElement);
}
else {
this.currentElement.parent.children.push(newElement);
}
this.currentElement = newElement;
}
else {
//This bullet represents a bullet at a higher level of indentation
for (var i = 0; i < (this.currentLevel - newLevel); i++) {
this.currentElement = this.currentElement.parent;
}
newElement.parent = this.currentElement.parent;
this.currentElement.parent.children.push(newElement);
this.currentElement = newElement;
this.currentLevel = newLevel;
}
}
this.toString = function (node) {
if (node == undefined) {
node = this.currentElement;
}
var previous = '';
if (node.parent != undefined) {
previous = this.toString(node.parent);
}
var bullet = node.bullet ? node.bullet : '';
return previous + bullet;
}
this.toTree = function () {
return this.printNode(this.root, this).slice(1);
}
//node -> [node]
this.printNode = function (node, that) {
var children = _(node.children).map(function (child) {
return that.printNode(child, that);
}).flatten()
.map(function (bullet) {
return '*' + bullet;
}).value();
return [node.bullet].concat(children);
}
/*
Returns the level of the hierarchy that this bullet represents.
Capital Roman Numerals are 0, capital letters are 1, etc.
*/
this.bulletLevel = function (bullet) {
var level = _.indexOf(bulletExpression.exec(bullet),
bullet, 2) - 2;
//(i) could be either a letter or a Roman
if (bullet != '(i)' && bullet != '(v)' && bullet != 'I.'
&& bullet != 'V.') {
return level;
}
if (bullet == 'I.') {
//The only instance in which I. is intended to be a Roman is
//if it is at the highest level
if (this.currentElement == this.root) {
return 0;
}
return 1;
}
if (bullet == 'V.') {
if(this.currentLevel == 0){
return 0;
}
return 1;
}
var relevantElement;
if (this.currentLevel == 5) {
relevantElement = this.currentElement;
}
else {
relevantElement = this.currentElement.parent;
}
if ((relevantElement.bullet != '(h)' && bullet == '(i)') ||
(relevantElement.bullet != '(u)' && bullet == '(v)')) {
return 6;
}
return level;
}
};
if (!inChrome()) {
module.exports = Stack;
}