occam-dom 4.0.16 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/main.js +15 -0
- package/example.js +38032 -0
- package/index.html +47 -0
- package/lib/constants.js +13 -0
- package/lib/example/constants.js +22 -0
- package/lib/example/utilities/query.js +23 -0
- package/lib/example/utilities/token.js +28 -0
- package/lib/example/view/div/sizeable.js +39 -0
- package/lib/example/view/input/maximumDepth.js +143 -0
- package/lib/example/view/input.js +39 -0
- package/lib/example/view/subHeading.js +39 -0
- package/lib/example/view/textarea/content.js +142 -0
- package/lib/example/view/textarea/expressions.js +143 -0
- package/lib/example/view/textarea/outerNodes.js +147 -0
- package/lib/example/view/textarea/parseTree/inner.js +157 -0
- package/lib/example/view/textarea/parseTree/outer.js +126 -0
- package/lib/example/view/textarea/parseTree.js +148 -0
- package/lib/example/view/textarea.js +39 -0
- package/lib/example/view.js +245 -0
- package/lib/example.js +19 -0
- package/lib/index.js +27 -0
- package/lib/node.js +302 -0
- package/lib/parseTree/childNodes.js +164 -0
- package/lib/parseTree/horizontalBranch.js +120 -0
- package/lib/parseTree/node.js +145 -0
- package/lib/parseTree/string.js +109 -0
- package/lib/parseTree/verticalBranch.js +184 -0
- package/lib/parseTree.js +191 -0
- package/lib/utilities/node.js +81 -0
- package/package.json +3 -2
- package/src/constants.js +3 -0
- package/src/example/constants.js +4 -0
- package/src/example/utilities/query.js +21 -0
- package/src/example/utilities/token.js +19 -0
- package/src/example/view/div/sizeable.js +12 -0
- package/src/example/view/input/maximumDepth.js +35 -0
- package/src/example/view/input.js +14 -0
- package/src/example/view/subHeading.js +16 -0
- package/src/example/view/textarea/content.js +33 -0
- package/src/example/view/textarea/expressions.js +39 -0
- package/src/example/view/textarea/outerNodes.js +48 -0
- package/src/example/view/textarea/parseTree/inner.js +24 -0
- package/src/example/view/textarea/parseTree/outer.js +17 -0
- package/src/example/view/textarea/parseTree.js +28 -0
- package/src/example/view/textarea.js +18 -0
- package/src/example/view.js +137 -0
- package/src/example.js +21 -0
- package/src/index.js +4 -0
- package/src/node.js +221 -0
- package/src/parseTree/childNodes.js +108 -0
- package/src/parseTree/horizontalBranch.js +32 -0
- package/src/parseTree/node.js +77 -0
- package/src/parseTree/string.js +18 -0
- package/src/parseTree/verticalBranch.js +77 -0
- package/src/parseTree.js +141 -0
- package/src/utilities/node.js +104 -0
package/src/node.js
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import NodeParseTree from "./parseTree/node";
|
|
4
|
+
|
|
5
|
+
import { EMPTY_STRING } from "./constants";
|
|
6
|
+
|
|
7
|
+
export default class Node {
|
|
8
|
+
constructor(outerNode, parentNode, childNodes) {
|
|
9
|
+
this.outerNode = outerNode;
|
|
10
|
+
this.parentNode = parentNode;
|
|
11
|
+
this.childNodes = childNodes;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
getOuterNode() {
|
|
15
|
+
return this.outerNode;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getParentNode() {
|
|
19
|
+
return this.parentNode;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
getChildNodes() {
|
|
23
|
+
return this.childNodes;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
setOuterNode(outerNode) {
|
|
27
|
+
this.outerNode = outerNode;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
setParentNode(parentNode) {
|
|
31
|
+
this.parentNode = parentNode;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
setChildNodes(childNodes) {
|
|
35
|
+
this.childNodes = childNodes;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
mapChildNode(callback) { return this.childNodes.map(callback); }
|
|
39
|
+
|
|
40
|
+
someChildNode(callback) { return this.childNodes.some(callback); }
|
|
41
|
+
|
|
42
|
+
findChildNode(callback) { return this.childNodes.find(callback); }
|
|
43
|
+
|
|
44
|
+
everyChildNode(callback) { return this.childNodes.every(callback); }
|
|
45
|
+
|
|
46
|
+
filterChildNode(callback) { return this.childNodes.filter(callback); }
|
|
47
|
+
|
|
48
|
+
reduceChildNode(callback, initialValue) { return this.childNodes.reduce(callback, initialValue); }
|
|
49
|
+
|
|
50
|
+
forEachChildNode(callback) { this.childNodes.forEach(callback); }
|
|
51
|
+
|
|
52
|
+
setChildNodesParentNode(childNodes) {
|
|
53
|
+
if (childNodes === undefined) {
|
|
54
|
+
childNodes = [
|
|
55
|
+
...this.childNodes
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const parentNode = this;
|
|
60
|
+
|
|
61
|
+
childNodes.forEach((childNode) => {
|
|
62
|
+
childNode.setParentNode(parentNode);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
resetChildNodesParentNode(childNodes) {
|
|
67
|
+
if (childNodes === undefined) {
|
|
68
|
+
childNodes = [
|
|
69
|
+
...this.childNodes
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const parentNode = null;
|
|
74
|
+
|
|
75
|
+
childNodes.forEach((childNode) => {
|
|
76
|
+
childNode.setParentNode(parentNode);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
addChildNode(addedChildNode, startIndex) {
|
|
81
|
+
const addedChildNodes = [
|
|
82
|
+
addedChildNode
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
this.addChildNodes(addedChildNodes, startIndex);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
addChildNodes(addedChildNodes, startIndex) {
|
|
89
|
+
const deleteCount = 0;
|
|
90
|
+
|
|
91
|
+
this.spliceChildNodes(startIndex, deleteCount, addedChildNodes);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
removeChildNode(removedChildNode) {
|
|
95
|
+
let removedChildNodes;
|
|
96
|
+
|
|
97
|
+
removedChildNodes = [
|
|
98
|
+
removedChildNode
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
removedChildNodes = this.removeChildNodes(removedChildNodes);
|
|
102
|
+
|
|
103
|
+
return removedChildNodes;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
removeChildNodes(removedChildNodes) {
|
|
107
|
+
if (removedChildNodes === undefined) {
|
|
108
|
+
removedChildNodes = [
|
|
109
|
+
...this.childNodes
|
|
110
|
+
];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const removedChildNodesLength = removedChildNodes.length;
|
|
114
|
+
|
|
115
|
+
if (removedChildNodesLength === 0) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const firstReplacedChildNode = first(removedChildNodes),
|
|
120
|
+
firstIndex = this.childNodes.indexOf(firstReplacedChildNode),
|
|
121
|
+
startIndex = firstIndex, ///
|
|
122
|
+
deleteCount = removedChildNodesLength, ///
|
|
123
|
+
addedChildNodes = [];
|
|
124
|
+
|
|
125
|
+
removedChildNodes = this.spliceChildNodes(startIndex, deleteCount, addedChildNodes);
|
|
126
|
+
|
|
127
|
+
return removedChildNodes;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
replaceChildNode(replacedChildNode, replacementChildNodes) {
|
|
131
|
+
const replacedChildNodes = [
|
|
132
|
+
replacedChildNode
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
this.replaceChildNodes(replacedChildNodes, replacementChildNodes);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
replaceChildNodes(replacedChildNodes, replacementChildNodes) {
|
|
139
|
+
const replacedChildNodesLength = replacedChildNodes.length,
|
|
140
|
+
firstReplacedChildNode = first(replacedChildNodes),
|
|
141
|
+
firstIndex = this.childNodes.indexOf(firstReplacedChildNode),
|
|
142
|
+
startIndex = firstIndex, ///
|
|
143
|
+
deleteCount = replacedChildNodesLength; ///
|
|
144
|
+
|
|
145
|
+
this.spliceChildNodes(startIndex, deleteCount, replacementChildNodes);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
spliceChildNodes(startIndex, deleteCount, addedChildNodes = []) {
|
|
149
|
+
const removedChildNodes = this.childNodes.splice(startIndex, deleteCount, ...addedChildNodes);
|
|
150
|
+
|
|
151
|
+
this.resetChildNodesParentNode(removedChildNodes);
|
|
152
|
+
|
|
153
|
+
this.setChildNodesParentNode(addedChildNodes);
|
|
154
|
+
|
|
155
|
+
return removedChildNodes;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
sliceChildNodes(startIndex, endIndex = Infinity) {
|
|
159
|
+
const childNodes = this.childNodes.slice(startIndex, endIndex);
|
|
160
|
+
|
|
161
|
+
return childNodes;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
asString() {
|
|
165
|
+
let string = EMPTY_STRING;
|
|
166
|
+
|
|
167
|
+
if (this.outerNode !== null) {
|
|
168
|
+
const nodeTerminalNode = this.outerNode.isTerminalNode();
|
|
169
|
+
|
|
170
|
+
if (nodeTerminalNode) {
|
|
171
|
+
const terminalNode = this.outerNode,
|
|
172
|
+
type = terminalNode.getType(),
|
|
173
|
+
content = terminalNode.getContent();
|
|
174
|
+
|
|
175
|
+
string = `"${content}" [${type}]`;
|
|
176
|
+
} else {
|
|
177
|
+
const nonTerminalNode = this.outerNode,
|
|
178
|
+
ruleName = nonTerminalNode.getRuleName();
|
|
179
|
+
|
|
180
|
+
string = ruleName; ///
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return string;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
asParseTree() {
|
|
188
|
+
const node = this, ///
|
|
189
|
+
nodeParseTree = NodeParseTree.fromNode(node),
|
|
190
|
+
parseTree = nodeParseTree; ///
|
|
191
|
+
|
|
192
|
+
return parseTree;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
static fromNothing(Class) {
|
|
196
|
+
if (Class === undefined) {
|
|
197
|
+
Class = Node; ///
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const outerNode = null,
|
|
201
|
+
parentNode = null,
|
|
202
|
+
childNodes = [],
|
|
203
|
+
node = new Class(outerNode, parentNode, childNodes);
|
|
204
|
+
|
|
205
|
+
return node;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
static fromOuterNode(Class, outerNode) {
|
|
209
|
+
if (outerNode === undefined) {
|
|
210
|
+
outerNode = Class; ///
|
|
211
|
+
|
|
212
|
+
Class = Node; ///
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const parentNode = null,
|
|
216
|
+
childNodes = [],
|
|
217
|
+
node = new Class(outerNode, parentNode, childNodes);
|
|
218
|
+
|
|
219
|
+
return node;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { arrayUtilities } from "necessary";
|
|
4
|
+
|
|
5
|
+
import VerticalBranchParseTree from "./verticalBranch";
|
|
6
|
+
import HorizontalBranchParseTree from "./horizontalBranch";
|
|
7
|
+
|
|
8
|
+
const { first } = arrayUtilities;
|
|
9
|
+
|
|
10
|
+
export default class ChildNodesParseTree extends VerticalBranchParseTree {
|
|
11
|
+
static fromChildNodes(childNodes) {
|
|
12
|
+
let childNodesParseTree = null;
|
|
13
|
+
|
|
14
|
+
const childNodesLength = childNodes.length;
|
|
15
|
+
|
|
16
|
+
if (childNodesLength > 0) {
|
|
17
|
+
const childNodeParseTrees = childNodes.reduce((childNodeParseTrees, childNode) => {
|
|
18
|
+
const childNodeParseTree = childNode.asParseTree();
|
|
19
|
+
|
|
20
|
+
childNodeParseTrees.push(childNodeParseTree);
|
|
21
|
+
|
|
22
|
+
return childNodeParseTrees;
|
|
23
|
+
}, []),
|
|
24
|
+
childNodeParseTreesLength = childNodeParseTrees.length;
|
|
25
|
+
|
|
26
|
+
if (childNodeParseTreesLength === 1) {
|
|
27
|
+
const firstChildNodeParseTree = first(childNodeParseTrees);
|
|
28
|
+
|
|
29
|
+
childNodesParseTree = firstChildNodeParseTree; ///
|
|
30
|
+
} else {
|
|
31
|
+
let firstVerticalBranchPosition,
|
|
32
|
+
lastVerticalBranchPosition = 0,
|
|
33
|
+
childNodeParseTreesWidth = 0,
|
|
34
|
+
childNodeParseTreesDepth = 0;
|
|
35
|
+
|
|
36
|
+
childNodeParseTrees.forEach((childNodeParseTree, index) => {
|
|
37
|
+
const childNodeParseTreeWidth = childNodeParseTree.getWidth(),
|
|
38
|
+
childNodeParseTreeDepth = childNodeParseTree.getDepth();
|
|
39
|
+
|
|
40
|
+
if (index === 0) {
|
|
41
|
+
const firstChildNodeParseTree = childNodeParseTree,
|
|
42
|
+
firstChildNodeParseTreeVerticalBranchPosition = firstChildNodeParseTree.getVerticalBranchPosition();
|
|
43
|
+
|
|
44
|
+
firstVerticalBranchPosition = firstChildNodeParseTreeVerticalBranchPosition;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (index === childNodeParseTreesLength - 1) {
|
|
48
|
+
const lastChildNodeParseTree = childNodeParseTree,
|
|
49
|
+
lastChildNodeParseTreeVerticalBranchPosition = lastChildNodeParseTree.getVerticalBranchPosition();
|
|
50
|
+
|
|
51
|
+
lastVerticalBranchPosition += lastChildNodeParseTreeVerticalBranchPosition;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (index < childNodeParseTreesLength - 1) {
|
|
55
|
+
lastVerticalBranchPosition += childNodeParseTreeWidth;
|
|
56
|
+
lastVerticalBranchPosition += 1;
|
|
57
|
+
|
|
58
|
+
childNodeParseTreesWidth += 1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
childNodeParseTreesWidth += childNodeParseTreeWidth;
|
|
62
|
+
childNodeParseTreesDepth = Math.max(childNodeParseTreesDepth, childNodeParseTreeDepth);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const width = lastVerticalBranchPosition - firstVerticalBranchPosition + 1,
|
|
66
|
+
verticalBranchParseTree = VerticalBranchParseTree.fromWidth(width),
|
|
67
|
+
horizontalBranchParseTree = HorizontalBranchParseTree.fromWidth(width),
|
|
68
|
+
leftMarginWidth = firstVerticalBranchPosition,
|
|
69
|
+
rightMarginWidth = childNodeParseTreesWidth - width - leftMarginWidth;
|
|
70
|
+
|
|
71
|
+
verticalBranchParseTree.addLeftMargin(leftMarginWidth);
|
|
72
|
+
verticalBranchParseTree.addRightMargin(rightMarginWidth);
|
|
73
|
+
horizontalBranchParseTree.addLeftMargin(leftMarginWidth);
|
|
74
|
+
horizontalBranchParseTree.addRightMargin(rightMarginWidth);
|
|
75
|
+
|
|
76
|
+
const verticalBranchPosition = verticalBranchParseTree.getVerticalBranchPosition(),
|
|
77
|
+
depth = childNodeParseTreesDepth; ///
|
|
78
|
+
|
|
79
|
+
childNodesParseTree = VerticalBranchParseTree.fromDepthAndVerticalBranchPosition(ChildNodesParseTree, depth, verticalBranchPosition);
|
|
80
|
+
|
|
81
|
+
childNodeParseTrees.forEach((childNodeParseTree, index) => {
|
|
82
|
+
const childNodeParseTreeDepth = childNodeParseTree.getDepth(),
|
|
83
|
+
clonedChildNodeParseTree = childNodeParseTree.clone();
|
|
84
|
+
|
|
85
|
+
if (index < childNodeParseTreesLength - 1) {
|
|
86
|
+
const rightMarginWidth = 1;
|
|
87
|
+
|
|
88
|
+
clonedChildNodeParseTree.addRightMargin(rightMarginWidth);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (childNodeParseTreeDepth < childNodeParseTreesDepth) {
|
|
92
|
+
const bottomMarginDepth = childNodeParseTreesDepth - childNodeParseTreeDepth;
|
|
93
|
+
|
|
94
|
+
clonedChildNodeParseTree.addBottomMargin(bottomMarginDepth);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
childNodesParseTree.appendToRight(clonedChildNodeParseTree);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
childNodesParseTree.appendToTop(horizontalBranchParseTree);
|
|
101
|
+
|
|
102
|
+
childNodesParseTree.appendToTop(verticalBranchParseTree);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return childNodesParseTree;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { characters } from "necessary";
|
|
4
|
+
|
|
5
|
+
import ParseTree from "../parseTree";
|
|
6
|
+
|
|
7
|
+
import { EMPTY_STRING } from "../constants";
|
|
8
|
+
|
|
9
|
+
const { DASH_CHARACTER } = characters;
|
|
10
|
+
|
|
11
|
+
export default class HorizontalBranchParseTree extends ParseTree {
|
|
12
|
+
static fromWidth(width) {
|
|
13
|
+
const string = stringFromCharactersWidth(width, DASH_CHARACTER),
|
|
14
|
+
line = string, ///
|
|
15
|
+
lines = [
|
|
16
|
+
line
|
|
17
|
+
],
|
|
18
|
+
horizontalBranchParseTree = new HorizontalBranchParseTree(lines);
|
|
19
|
+
|
|
20
|
+
return horizontalBranchParseTree;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function stringFromCharactersWidth(charactersWidth, character) {
|
|
25
|
+
let string = EMPTY_STRING;
|
|
26
|
+
|
|
27
|
+
for (let index = 0; index < charactersWidth; index++) {
|
|
28
|
+
string += character;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return string;
|
|
32
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import StringParseTree from "./string";
|
|
4
|
+
import ChildNodesParseTree from "./childNodes";
|
|
5
|
+
import VerticalBranchParseTree from "./verticalBranch";
|
|
6
|
+
|
|
7
|
+
export default class NodeParseTree extends VerticalBranchParseTree {
|
|
8
|
+
static fromNode(node) {
|
|
9
|
+
let nodeParseTree;
|
|
10
|
+
|
|
11
|
+
const childNodes = node.getChildNodes(),
|
|
12
|
+
ruleNameParseTree = StringParseTree.fromNode(node),
|
|
13
|
+
childNodesParseTree = ChildNodesParseTree.fromChildNodes(childNodes);
|
|
14
|
+
|
|
15
|
+
if (childNodesParseTree === null) {
|
|
16
|
+
const ruleNameParseTreeDepth = ruleNameParseTree.getDepth(),
|
|
17
|
+
ruleNameParseTreeVerticalBranchPosition = ruleNameParseTree.getVerticalBranchPosition(),
|
|
18
|
+
verticalBranchPosition = ruleNameParseTreeVerticalBranchPosition, ///
|
|
19
|
+
depth = ruleNameParseTreeDepth; ///
|
|
20
|
+
|
|
21
|
+
nodeParseTree = VerticalBranchParseTree.fromDepthAndVerticalBranchPosition(NodeParseTree, depth, verticalBranchPosition);
|
|
22
|
+
|
|
23
|
+
nodeParseTree.appendToRight(ruleNameParseTree);
|
|
24
|
+
} else {
|
|
25
|
+
let ruleNameParseTreeVerticalBranchPosition = ruleNameParseTree.getVerticalBranchPosition();
|
|
26
|
+
|
|
27
|
+
const childNodesParseTreeVerticalBranchPosition = childNodesParseTree.getVerticalBranchPosition(),
|
|
28
|
+
verticalBranchPositionsDifference = ruleNameParseTreeVerticalBranchPosition - childNodesParseTreeVerticalBranchPosition;
|
|
29
|
+
|
|
30
|
+
let leftMarginWidth;
|
|
31
|
+
|
|
32
|
+
if (false) {
|
|
33
|
+
///
|
|
34
|
+
} else if (verticalBranchPositionsDifference < 0) {
|
|
35
|
+
leftMarginWidth = -verticalBranchPositionsDifference;
|
|
36
|
+
|
|
37
|
+
ruleNameParseTree.addLeftMargin(leftMarginWidth);
|
|
38
|
+
} else if (verticalBranchPositionsDifference > 0) {
|
|
39
|
+
leftMarginWidth = +verticalBranchPositionsDifference;
|
|
40
|
+
|
|
41
|
+
childNodesParseTree.addLeftMargin(leftMarginWidth);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const ruleNameParseTreeWidth = ruleNameParseTree.getWidth(),
|
|
45
|
+
childNodesParseTreeWidth = childNodesParseTree.getWidth(),
|
|
46
|
+
widthsDifference = ruleNameParseTreeWidth - childNodesParseTreeWidth;
|
|
47
|
+
|
|
48
|
+
let rightMarginWidth;
|
|
49
|
+
|
|
50
|
+
if (false) {
|
|
51
|
+
///
|
|
52
|
+
} else if (widthsDifference < 0) {
|
|
53
|
+
rightMarginWidth = -widthsDifference;
|
|
54
|
+
|
|
55
|
+
ruleNameParseTree.addRightMargin(rightMarginWidth);
|
|
56
|
+
} else if (widthsDifference > 0) {
|
|
57
|
+
rightMarginWidth = +widthsDifference;
|
|
58
|
+
|
|
59
|
+
childNodesParseTree.addRightMargin(rightMarginWidth);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
ruleNameParseTreeVerticalBranchPosition = ruleNameParseTree.getVerticalBranchPosition();
|
|
63
|
+
|
|
64
|
+
const ruleNameParseTreeDepth = ruleNameParseTree.getDepth(),
|
|
65
|
+
verticalBranchPosition = ruleNameParseTreeVerticalBranchPosition, ///
|
|
66
|
+
depth = ruleNameParseTreeDepth; ///
|
|
67
|
+
|
|
68
|
+
nodeParseTree = VerticalBranchParseTree.fromDepthAndVerticalBranchPosition(NodeParseTree, depth, verticalBranchPosition);
|
|
69
|
+
|
|
70
|
+
nodeParseTree.appendToRight(ruleNameParseTree);
|
|
71
|
+
|
|
72
|
+
nodeParseTree.appendToBottom(childNodesParseTree);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return nodeParseTree;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import VerticalBranchParseTree from "./verticalBranch";
|
|
4
|
+
|
|
5
|
+
export default class StringParseTree extends VerticalBranchParseTree {
|
|
6
|
+
static fromNode(node) {
|
|
7
|
+
const string = node.asString(),
|
|
8
|
+
stringLength = string.length,
|
|
9
|
+
verticalBranchParseTreeWidth = stringLength, ///
|
|
10
|
+
verticalBranchParseTree = VerticalBranchParseTree.fromWidth(verticalBranchParseTreeWidth),
|
|
11
|
+
verticalBranchPosition = verticalBranchParseTree.getVerticalBranchPosition(),
|
|
12
|
+
ruleNameParseTree = VerticalBranchParseTree.fromStringAndVerticalBranchPosition(StringParseTree, string, verticalBranchPosition);
|
|
13
|
+
|
|
14
|
+
ruleNameParseTree.appendToTop(verticalBranchParseTree);
|
|
15
|
+
|
|
16
|
+
return ruleNameParseTree;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { characters } from "necessary";
|
|
4
|
+
|
|
5
|
+
import ParseTree from "../parseTree";
|
|
6
|
+
|
|
7
|
+
import { EMPTY_STRING } from "../constants";
|
|
8
|
+
|
|
9
|
+
const { BAR_CHARACTER } = characters;
|
|
10
|
+
|
|
11
|
+
export default class VerticalBranchParseTree extends ParseTree {
|
|
12
|
+
constructor(lines, verticalBranchPosition) {
|
|
13
|
+
super(lines);
|
|
14
|
+
|
|
15
|
+
this.verticalBranchPosition = verticalBranchPosition;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getVerticalBranchPosition() {
|
|
19
|
+
return this.verticalBranchPosition;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
addLeftMargin(leftMarginWidth) {
|
|
23
|
+
super.addLeftMargin(leftMarginWidth);
|
|
24
|
+
|
|
25
|
+
this.verticalBranchPosition += leftMarginWidth; ///
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
static fromWidth(width) {
|
|
29
|
+
const string = BAR_CHARACTER,
|
|
30
|
+
verticalBranchPosition = 0,
|
|
31
|
+
verticalBranchParseTree = VerticalBranchParseTree.fromStringAndVerticalBranchPosition(VerticalBranchParseTree, string, verticalBranchPosition),
|
|
32
|
+
leftMarginWidth = Math.floor(width/2),
|
|
33
|
+
rightMarginWidth = width - leftMarginWidth - 1;
|
|
34
|
+
|
|
35
|
+
verticalBranchParseTree.addLeftMargin(leftMarginWidth);
|
|
36
|
+
verticalBranchParseTree.addRightMargin(rightMarginWidth);
|
|
37
|
+
|
|
38
|
+
return verticalBranchParseTree;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static fromDepthAndVerticalBranchPosition(Class, depth, verticalBranchPosition) {
|
|
42
|
+
const lines = linesFromDepth(depth),
|
|
43
|
+
verticalBranchParseTree = new Class(lines, verticalBranchPosition);
|
|
44
|
+
|
|
45
|
+
return verticalBranchParseTree;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static fromStringAndVerticalBranchPosition(Class, string, verticalBranchPosition) {
|
|
49
|
+
if (verticalBranchPosition === undefined) {
|
|
50
|
+
verticalBranchPosition = string; ///
|
|
51
|
+
|
|
52
|
+
string = Class; ///
|
|
53
|
+
|
|
54
|
+
Class = ParseTree; ///
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const line = string, ///
|
|
58
|
+
lines = [
|
|
59
|
+
line
|
|
60
|
+
],
|
|
61
|
+
verticalBranchParseTree = new Class(lines, verticalBranchPosition);
|
|
62
|
+
|
|
63
|
+
return verticalBranchParseTree;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function linesFromDepth(depth) {
|
|
68
|
+
const lines = [];
|
|
69
|
+
|
|
70
|
+
let index = 0;
|
|
71
|
+
|
|
72
|
+
while (index < depth) {
|
|
73
|
+
lines[index++] = EMPTY_STRING;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return lines;
|
|
77
|
+
}
|
package/src/parseTree.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { characters, arrayUtilities } from "necessary";
|
|
4
|
+
|
|
5
|
+
import { EMPTY_STRING } from "./constants";
|
|
6
|
+
|
|
7
|
+
const { last } = arrayUtilities,
|
|
8
|
+
{ NEW_LINE_CHARACTER, SPACE_CHARACTER } = characters;
|
|
9
|
+
|
|
10
|
+
export default class ParseTree {
|
|
11
|
+
constructor(lines) {
|
|
12
|
+
this.lines = lines;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
clone() {
|
|
16
|
+
const lines = this.lines.slice(), ///
|
|
17
|
+
parseTree = new ParseTree(lines);
|
|
18
|
+
|
|
19
|
+
return parseTree;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
getWidth() {
|
|
23
|
+
let width;
|
|
24
|
+
|
|
25
|
+
let linesLength = this.lines.length;
|
|
26
|
+
|
|
27
|
+
if (linesLength === 0) {
|
|
28
|
+
width = 0;
|
|
29
|
+
} else {
|
|
30
|
+
const lastLine = last(this.lines),
|
|
31
|
+
lastLineLength = lastLine.length;
|
|
32
|
+
|
|
33
|
+
width = lastLineLength; ///
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return width;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
getDepth() {
|
|
40
|
+
const linesLength = this.lines.length,
|
|
41
|
+
depth = linesLength; ///
|
|
42
|
+
|
|
43
|
+
return depth;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
forEachLine(callback) {
|
|
47
|
+
this.lines.forEach(callback);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
appendToTop(parseTree) {
|
|
51
|
+
parseTree.forEachLine((line) => {
|
|
52
|
+
this.lines.unshift(line);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
appendToLeft(parseTree) {
|
|
57
|
+
parseTree.forEachLine((line, index) => {
|
|
58
|
+
this.lines[index] = line + this.lines[index];
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
appendToRight(parseTree) {
|
|
63
|
+
parseTree.forEachLine((line, index) => {
|
|
64
|
+
this.lines[index] = this.lines[index] + line;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
appendToBottom(parseTree) {
|
|
69
|
+
parseTree.forEachLine((line) => {
|
|
70
|
+
this.lines.push(line);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
addTopMargin(topMarginDepth) {
|
|
75
|
+
const width = this.getWidth(),
|
|
76
|
+
topMarginWidth = width, ///
|
|
77
|
+
topMarginString = marginStringFromMarginWidth(topMarginWidth);
|
|
78
|
+
|
|
79
|
+
for (let index = 0; index < topMarginDepth; index++) {
|
|
80
|
+
this.lines.unshift(topMarginString);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
addLeftMargin(leftMarginWidth) {
|
|
85
|
+
const leftMarginString = marginStringFromMarginWidth(leftMarginWidth),
|
|
86
|
+
linesLength = this.lines.length;
|
|
87
|
+
|
|
88
|
+
for (let index = 0; index < linesLength; index++) {
|
|
89
|
+
this.lines[index] = leftMarginString + this.lines[index];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
addRightMargin(rightMarginWidth) {
|
|
94
|
+
const rightMarginString = marginStringFromMarginWidth(rightMarginWidth),
|
|
95
|
+
linesLength = this.lines.length;
|
|
96
|
+
|
|
97
|
+
for (let index = 0; index < linesLength; index++) {
|
|
98
|
+
this.lines[index] = this.lines[index] + rightMarginString;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
addBottomMargin(bottomMarginDepth) {
|
|
103
|
+
const width = this.getWidth(),
|
|
104
|
+
bottomMarginWidth = width, ///
|
|
105
|
+
bottomMarginString = marginStringFromMarginWidth(bottomMarginWidth);
|
|
106
|
+
|
|
107
|
+
for (let index = 0; index < bottomMarginDepth; index++) {
|
|
108
|
+
this.lines.push(bottomMarginString);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
popLine() { return this.lines.pop(); }
|
|
113
|
+
|
|
114
|
+
shiftLine() { return this.lines.shift(); }
|
|
115
|
+
|
|
116
|
+
pushLine(line) { this.lines.push(line); }
|
|
117
|
+
|
|
118
|
+
unshiftLine(line) { this.lines.unshift(line); }
|
|
119
|
+
|
|
120
|
+
asString() {
|
|
121
|
+
const string = this.lines.reduce((string, line) => {
|
|
122
|
+
string += line + NEW_LINE_CHARACTER;
|
|
123
|
+
|
|
124
|
+
return string;
|
|
125
|
+
}, EMPTY_STRING);
|
|
126
|
+
|
|
127
|
+
return string;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function marginStringFromMarginWidth(marginWidth, spaceCharacter) {
|
|
132
|
+
spaceCharacter = spaceCharacter || SPACE_CHARACTER;
|
|
133
|
+
|
|
134
|
+
let marginString = EMPTY_STRING;
|
|
135
|
+
|
|
136
|
+
for (let index = 0; index < marginWidth; index++) {
|
|
137
|
+
marginString += spaceCharacter;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return marginString;
|
|
141
|
+
}
|