@jdeighan/coffee-utils 8.0.4 → 8.0.5
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/package.json +1 -1
- package/src/Section.coffee +1 -1
- package/src/Section.js +2 -1
- package/src/SectionMap.coffee +94 -94
- package/src/SectionMap.js +120 -115
- package/src/block_utils.coffee +17 -5
- package/src/block_utils.js +17 -5
package/package.json
CHANGED
package/src/Section.coffee
CHANGED
package/src/Section.js
CHANGED
package/src/SectionMap.coffee
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
isString, isHash, isArray, isUniqueTree, isNonEmptyString,
|
|
6
6
|
} from '@jdeighan/coffee-utils'
|
|
7
7
|
import {arrayToBlock} from '@jdeighan/coffee-utils/block'
|
|
8
|
+
import {indented} from '@jdeighan/coffee-utils/indent'
|
|
8
9
|
import {debug} from '@jdeighan/coffee-utils/debug'
|
|
9
10
|
import {Section} from '@jdeighan/coffee-utils/section'
|
|
10
11
|
|
|
@@ -12,110 +13,125 @@ import {Section} from '@jdeighan/coffee-utils/section'
|
|
|
12
13
|
|
|
13
14
|
isSectionName = (name) ->
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
return name.match(/^[a-z][a-z0-9]*/)
|
|
16
|
+
return isString(name) && name.match(/^[a-z][a-z0-9]*/)
|
|
17
17
|
|
|
18
18
|
# ---------------------------------------------------------------------------
|
|
19
19
|
|
|
20
20
|
isSetName = (name) ->
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
return name.match(/^[A-Z][a-z0-9]*/)
|
|
22
|
+
return isString(name) && name.match(/^[A-Z][a-z0-9]*/)
|
|
24
23
|
|
|
25
24
|
# ---------------------------------------------------------------------------
|
|
26
25
|
|
|
27
26
|
export class SectionMap
|
|
28
27
|
|
|
29
|
-
constructor: (
|
|
30
|
-
# ---
|
|
28
|
+
constructor: (lSectionTree) ->
|
|
29
|
+
# --- lSectionTree is a tree of section names
|
|
31
30
|
|
|
32
|
-
debug "enter SectionMap()",
|
|
33
|
-
@
|
|
31
|
+
debug "enter SectionMap()", lSectionTree
|
|
32
|
+
@lSectionTree = lSectionTree # a tree of section names
|
|
34
33
|
@hSets = {}
|
|
35
34
|
@hSections = {}
|
|
36
|
-
@addSections
|
|
35
|
+
@addSections lSectionTree
|
|
37
36
|
debug "return from SectionMap()", @hSections
|
|
38
37
|
|
|
39
38
|
# ..........................................................
|
|
40
39
|
|
|
41
|
-
# --- TODO: Allow array to start with a set name ---
|
|
42
|
-
|
|
43
40
|
addSections: (desc) ->
|
|
41
|
+
# --- returns a flat array of sections that were added
|
|
44
42
|
|
|
45
43
|
if isString(desc)
|
|
46
44
|
assert nonEmpty(desc), "empty section name"
|
|
47
|
-
assert desc
|
|
45
|
+
assert isSectionName(desc), "bad section name #{OL(desc)}"
|
|
48
46
|
assert (@hSections[desc] == undef), "duplicate section #{OL(desc)}"
|
|
49
|
-
@hSections[desc] = new Section()
|
|
47
|
+
@hSections[desc] = new Section(desc)
|
|
48
|
+
return [desc]
|
|
50
49
|
else
|
|
51
50
|
assert isArray(desc), "not an array or string #{OL(desc)}"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
# --- a generator - yield order is not guaranteed
|
|
58
|
-
|
|
59
|
-
allSections: (desc) ->
|
|
60
|
-
|
|
61
|
-
debug "enter allSections()"
|
|
62
|
-
if (desc == undef)
|
|
63
|
-
# --- We want to return all sections
|
|
64
|
-
debug "yield all sections"
|
|
65
|
-
for _,sect of @hSections
|
|
66
|
-
yield sect
|
|
67
|
-
else if isString(desc)
|
|
68
|
-
if isSectionName(desc)
|
|
69
|
-
debug "yield section #{OL(desc)}"
|
|
70
|
-
yield @section(desc)
|
|
71
|
-
else if isSetName(desc)
|
|
72
|
-
debug "expand set #{OL(desc)}"
|
|
73
|
-
debug 'hSets', @hSets
|
|
74
|
-
lNames = @hSets[desc]
|
|
75
|
-
assert defined(lNames), "no set named #{OL(desc)}"
|
|
76
|
-
debug "set #{desc}", lNames
|
|
77
|
-
for name in lNames
|
|
78
|
-
debug "yield section #{OL(desc)}"
|
|
79
|
-
yield @section(name)
|
|
80
|
-
else
|
|
81
|
-
croak "bad name #{OL(desc)}"
|
|
82
|
-
else
|
|
83
|
-
assert isArray(desc), "not an array"
|
|
84
|
-
for name in desc
|
|
85
|
-
debug "yield section #{OL(name)}"
|
|
86
|
-
assert isString(name), "not a string #{OL(name)}"
|
|
87
|
-
if isSectionName(name)
|
|
88
|
-
yield @section(name)
|
|
89
|
-
else if isSetName(name)
|
|
90
|
-
for _,sect of @hSets[name]
|
|
91
|
-
yield sect
|
|
51
|
+
name = undef
|
|
52
|
+
lParts = []
|
|
53
|
+
for item,i in desc
|
|
54
|
+
if (i==0) && isSetName(item)
|
|
55
|
+
name = item
|
|
92
56
|
else
|
|
93
|
-
|
|
94
|
-
|
|
57
|
+
lAdded = @addSections item
|
|
58
|
+
for item in lAdded
|
|
59
|
+
lParts.push item
|
|
60
|
+
if defined(name)
|
|
61
|
+
@addSet name, lParts
|
|
62
|
+
return lParts
|
|
95
63
|
return
|
|
96
64
|
|
|
97
65
|
# ..........................................................
|
|
98
66
|
|
|
99
|
-
addSet: (name,
|
|
67
|
+
addSet: (name, lSectionTree) ->
|
|
100
68
|
|
|
101
|
-
debug "enter addSet()", name,
|
|
69
|
+
debug "enter addSet()", name, lSectionTree
|
|
102
70
|
|
|
103
71
|
# --- check the name
|
|
104
72
|
assert isSetName(name), "not a valid set name #{OL(name)}"
|
|
105
73
|
|
|
106
|
-
# --- check
|
|
107
|
-
assert isArray(
|
|
108
|
-
for secName in
|
|
74
|
+
# --- check lSectionTree
|
|
75
|
+
assert isArray(lSectionTree), "arg 2 not an array"
|
|
76
|
+
for secName in lSectionTree
|
|
109
77
|
assert isNonEmptyString(secName),
|
|
110
78
|
"not a non-empty string #{OL(secName)}"
|
|
111
79
|
assert defined(@hSections[secName]),
|
|
112
80
|
"not a section name #{OL(secName)}"
|
|
113
81
|
|
|
114
|
-
@hSets[name] =
|
|
82
|
+
@hSets[name] = lSectionTree
|
|
115
83
|
debug 'hSets', @hSets
|
|
116
84
|
debug "return from addSet()"
|
|
117
85
|
return
|
|
118
86
|
|
|
87
|
+
# ..........................................................
|
|
88
|
+
# --- sections returned in depth-first order from section tree
|
|
89
|
+
# Set names are simply skipped
|
|
90
|
+
# yields: [<level>, <section>]
|
|
91
|
+
|
|
92
|
+
allSections: (desc=undef, level=0) ->
|
|
93
|
+
|
|
94
|
+
debug "enter allSections()", desc, level
|
|
95
|
+
if (desc == undef)
|
|
96
|
+
desc = @lSectionTree
|
|
97
|
+
if isArray(desc)
|
|
98
|
+
for item in desc
|
|
99
|
+
if isSectionName(item)
|
|
100
|
+
result = [level, @section(item)]
|
|
101
|
+
debug 'yield', result
|
|
102
|
+
yield result
|
|
103
|
+
else if isSetName(item)
|
|
104
|
+
pass
|
|
105
|
+
else
|
|
106
|
+
assert isArray(item), "not an array #{OL(item)}"
|
|
107
|
+
yield from @allSections(item, level+1)
|
|
108
|
+
else if isSectionName(desc)
|
|
109
|
+
result = [level, @section(desc)]
|
|
110
|
+
debug 'yield', result
|
|
111
|
+
yield result
|
|
112
|
+
else if isSetName(desc)
|
|
113
|
+
lTree = @hSets[desc]
|
|
114
|
+
assert defined(lTree), "Not a Set: #{OL(desc)}"
|
|
115
|
+
yield from @allSections(lTree, level)
|
|
116
|
+
else
|
|
117
|
+
croak "Bad item: #{OL(desc)}"
|
|
118
|
+
debug "return from allSections()"
|
|
119
|
+
return
|
|
120
|
+
|
|
121
|
+
# ..........................................................
|
|
122
|
+
|
|
123
|
+
getBlock: () ->
|
|
124
|
+
|
|
125
|
+
debug "enter getBlock()"
|
|
126
|
+
lParts = []
|
|
127
|
+
for [_, sect] from @allSections()
|
|
128
|
+
if sect.nonEmpty()
|
|
129
|
+
lParts.push sect.getBlock()
|
|
130
|
+
debug 'lParts', lParts
|
|
131
|
+
result = arrayToBlock(lParts)
|
|
132
|
+
debug "return from getBlock()", result
|
|
133
|
+
return result
|
|
134
|
+
|
|
119
135
|
# ..........................................................
|
|
120
136
|
|
|
121
137
|
section: (name) ->
|
|
@@ -129,27 +145,27 @@ export class SectionMap
|
|
|
129
145
|
firstSection: (name) ->
|
|
130
146
|
|
|
131
147
|
assert isSetName(name), "bad set name #{OL(name)}"
|
|
132
|
-
|
|
133
|
-
assert defined(
|
|
134
|
-
assert nonEmpty(
|
|
135
|
-
return @section(
|
|
148
|
+
lSectionTree = @hSets[name]
|
|
149
|
+
assert defined(lSectionTree), "no such set #{OL(name)}"
|
|
150
|
+
assert nonEmpty(lSectionTree), "empty section #{OL(name)}"
|
|
151
|
+
return @section(lSectionTree[0])
|
|
136
152
|
|
|
137
153
|
# ..........................................................
|
|
138
154
|
|
|
139
155
|
lastSection: (name) ->
|
|
140
156
|
|
|
141
157
|
assert isSetName(name), "bad set name #{OL(name)}"
|
|
142
|
-
|
|
143
|
-
assert defined(
|
|
144
|
-
assert nonEmpty(
|
|
145
|
-
return @section(
|
|
158
|
+
lSectionTree = @hSets[name]
|
|
159
|
+
assert defined(lSectionTree), "no such set #{OL(name)}"
|
|
160
|
+
assert nonEmpty(lSectionTree), "empty section #{OL(name)}"
|
|
161
|
+
return @section(lSectionTree[lSectionTree.length - 1])
|
|
146
162
|
|
|
147
163
|
# ..........................................................
|
|
148
164
|
|
|
149
165
|
length: (desc=undef) ->
|
|
150
166
|
|
|
151
167
|
result = 0
|
|
152
|
-
for sect from @allSections(desc)
|
|
168
|
+
for [_, sect] from @allSections(desc)
|
|
153
169
|
result += sect.length()
|
|
154
170
|
return result
|
|
155
171
|
|
|
@@ -169,7 +185,7 @@ export class SectionMap
|
|
|
169
185
|
|
|
170
186
|
indent: (desc=undef, level=1) ->
|
|
171
187
|
|
|
172
|
-
for sect from @allSections(desc)
|
|
188
|
+
for [_, sect] from @allSections(desc)
|
|
173
189
|
sect.indent(level)
|
|
174
190
|
return
|
|
175
191
|
|
|
@@ -194,28 +210,12 @@ export class SectionMap
|
|
|
194
210
|
|
|
195
211
|
# ..........................................................
|
|
196
212
|
|
|
197
|
-
|
|
213
|
+
getShape: () ->
|
|
198
214
|
|
|
199
|
-
debug "enter
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
debug "return from getBlock()", result
|
|
215
|
+
debug "enter getShape()"
|
|
216
|
+
lParts = []
|
|
217
|
+
for [level, sect] from @allSections()
|
|
218
|
+
lParts.push indented(sect.name, level)
|
|
219
|
+
result = arrayToBlock(lParts)
|
|
220
|
+
debug "return from getShape()", result
|
|
206
221
|
return result
|
|
207
|
-
|
|
208
|
-
# ..........................................................
|
|
209
|
-
|
|
210
|
-
accumBlock: (tree) ->
|
|
211
|
-
|
|
212
|
-
if isString(tree)
|
|
213
|
-
debug "accumBlock #{OL(tree)}"
|
|
214
|
-
block = @section(tree).getBlock()
|
|
215
|
-
if nonEmpty(block)
|
|
216
|
-
@lAllBlocks.push block
|
|
217
|
-
else
|
|
218
|
-
assert isArray(tree), "not an array"
|
|
219
|
-
for subtree in tree
|
|
220
|
-
@accumBlock subtree
|
|
221
|
-
return
|
package/src/SectionMap.js
CHANGED
|
@@ -22,6 +22,10 @@ import {
|
|
|
22
22
|
arrayToBlock
|
|
23
23
|
} from '@jdeighan/coffee-utils/block';
|
|
24
24
|
|
|
25
|
+
import {
|
|
26
|
+
indented
|
|
27
|
+
} from '@jdeighan/coffee-utils/indent';
|
|
28
|
+
|
|
25
29
|
import {
|
|
26
30
|
debug
|
|
27
31
|
} from '@jdeighan/coffee-utils/debug';
|
|
@@ -32,116 +36,131 @@ import {
|
|
|
32
36
|
|
|
33
37
|
// ---------------------------------------------------------------------------
|
|
34
38
|
isSectionName = function(name) {
|
|
35
|
-
|
|
36
|
-
return name.match(/^[a-z][a-z0-9]*/);
|
|
39
|
+
return isString(name) && name.match(/^[a-z][a-z0-9]*/);
|
|
37
40
|
};
|
|
38
41
|
|
|
39
42
|
// ---------------------------------------------------------------------------
|
|
40
43
|
isSetName = function(name) {
|
|
41
|
-
|
|
42
|
-
return name.match(/^[A-Z][a-z0-9]*/);
|
|
44
|
+
return isString(name) && name.match(/^[A-Z][a-z0-9]*/);
|
|
43
45
|
};
|
|
44
46
|
|
|
45
47
|
// ---------------------------------------------------------------------------
|
|
46
48
|
export var SectionMap = class SectionMap {
|
|
47
|
-
constructor(
|
|
48
|
-
// ---
|
|
49
|
-
debug("enter SectionMap()",
|
|
50
|
-
this.
|
|
49
|
+
constructor(lSectionTree) {
|
|
50
|
+
// --- lSectionTree is a tree of section names
|
|
51
|
+
debug("enter SectionMap()", lSectionTree);
|
|
52
|
+
this.lSectionTree = lSectionTree; // a tree of section names
|
|
51
53
|
this.hSets = {};
|
|
52
54
|
this.hSections = {};
|
|
53
|
-
this.addSections(
|
|
55
|
+
this.addSections(lSectionTree);
|
|
54
56
|
debug("return from SectionMap()", this.hSections);
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
// ..........................................................
|
|
58
|
-
|
|
59
|
-
// --- TODO: Allow array to start with a set name ---
|
|
60
60
|
addSections(desc) {
|
|
61
|
-
var i, item, len;
|
|
61
|
+
var i, item, j, k, lAdded, lParts, len, len1, name;
|
|
62
|
+
// --- returns a flat array of sections that were added
|
|
62
63
|
if (isString(desc)) {
|
|
63
64
|
assert(nonEmpty(desc), "empty section name");
|
|
64
|
-
assert(desc
|
|
65
|
+
assert(isSectionName(desc), `bad section name ${OL(desc)}`);
|
|
65
66
|
assert(this.hSections[desc] === undef, `duplicate section ${OL(desc)}`);
|
|
66
|
-
this.hSections[desc] = new Section();
|
|
67
|
+
this.hSections[desc] = new Section(desc);
|
|
68
|
+
return [desc];
|
|
67
69
|
} else {
|
|
68
70
|
assert(isArray(desc), `not an array or string ${OL(desc)}`);
|
|
69
|
-
|
|
71
|
+
name = undef;
|
|
72
|
+
lParts = [];
|
|
73
|
+
for (i = j = 0, len = desc.length; j < len; i = ++j) {
|
|
70
74
|
item = desc[i];
|
|
71
|
-
|
|
75
|
+
if ((i === 0) && isSetName(item)) {
|
|
76
|
+
name = item;
|
|
77
|
+
} else {
|
|
78
|
+
lAdded = this.addSections(item);
|
|
79
|
+
for (k = 0, len1 = lAdded.length; k < len1; k++) {
|
|
80
|
+
item = lAdded[k];
|
|
81
|
+
lParts.push(item);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
72
84
|
}
|
|
85
|
+
if (defined(name)) {
|
|
86
|
+
this.addSet(name, lParts);
|
|
87
|
+
}
|
|
88
|
+
return lParts;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ..........................................................
|
|
93
|
+
addSet(name, lSectionTree) {
|
|
94
|
+
var j, len, secName;
|
|
95
|
+
debug("enter addSet()", name, lSectionTree);
|
|
96
|
+
// --- check the name
|
|
97
|
+
assert(isSetName(name), `not a valid set name ${OL(name)}`);
|
|
98
|
+
// --- check lSectionTree
|
|
99
|
+
assert(isArray(lSectionTree), "arg 2 not an array");
|
|
100
|
+
for (j = 0, len = lSectionTree.length; j < len; j++) {
|
|
101
|
+
secName = lSectionTree[j];
|
|
102
|
+
assert(isNonEmptyString(secName), `not a non-empty string ${OL(secName)}`);
|
|
103
|
+
assert(defined(this.hSections[secName]), `not a section name ${OL(secName)}`);
|
|
73
104
|
}
|
|
105
|
+
this.hSets[name] = lSectionTree;
|
|
106
|
+
debug('hSets', this.hSets);
|
|
107
|
+
debug("return from addSet()");
|
|
74
108
|
}
|
|
75
109
|
|
|
76
110
|
// ..........................................................
|
|
77
|
-
// ---
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
111
|
+
// --- sections returned in depth-first order from section tree
|
|
112
|
+
// Set names are simply skipped
|
|
113
|
+
// yields: [<level>, <section>]
|
|
114
|
+
* allSections(desc = undef, level = 0) {
|
|
115
|
+
var item, j, lTree, len, result;
|
|
116
|
+
debug("enter allSections()", desc, level);
|
|
81
117
|
if (desc === undef) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
for (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
} else if (isSetName(desc)) {
|
|
94
|
-
debug(`expand set ${OL(desc)}`);
|
|
95
|
-
debug('hSets', this.hSets);
|
|
96
|
-
lNames = this.hSets[desc];
|
|
97
|
-
assert(defined(lNames), `no set named ${OL(desc)}`);
|
|
98
|
-
debug(`set ${desc}`, lNames);
|
|
99
|
-
for (i = 0, len = lNames.length; i < len; i++) {
|
|
100
|
-
name = lNames[i];
|
|
101
|
-
debug(`yield section ${OL(desc)}`);
|
|
102
|
-
yield this.section(name);
|
|
103
|
-
}
|
|
104
|
-
} else {
|
|
105
|
-
croak(`bad name ${OL(desc)}`);
|
|
106
|
-
}
|
|
107
|
-
} else {
|
|
108
|
-
assert(isArray(desc), "not an array");
|
|
109
|
-
for (j = 0, len1 = desc.length; j < len1; j++) {
|
|
110
|
-
name = desc[j];
|
|
111
|
-
debug(`yield section ${OL(name)}`);
|
|
112
|
-
assert(isString(name), `not a string ${OL(name)}`);
|
|
113
|
-
if (isSectionName(name)) {
|
|
114
|
-
yield this.section(name);
|
|
115
|
-
} else if (isSetName(name)) {
|
|
116
|
-
ref1 = this.hSets[name];
|
|
117
|
-
for (_ in ref1) {
|
|
118
|
-
sect = ref1[_];
|
|
119
|
-
yield sect;
|
|
120
|
-
}
|
|
118
|
+
desc = this.lSectionTree;
|
|
119
|
+
}
|
|
120
|
+
if (isArray(desc)) {
|
|
121
|
+
for (j = 0, len = desc.length; j < len; j++) {
|
|
122
|
+
item = desc[j];
|
|
123
|
+
if (isSectionName(item)) {
|
|
124
|
+
result = [level, this.section(item)];
|
|
125
|
+
debug('yield', result);
|
|
126
|
+
yield result;
|
|
127
|
+
} else if (isSetName(item)) {
|
|
128
|
+
pass;
|
|
121
129
|
} else {
|
|
122
|
-
|
|
130
|
+
assert(isArray(item), `not an array ${OL(item)}`);
|
|
131
|
+
yield* this.allSections(item, level + 1);
|
|
123
132
|
}
|
|
124
133
|
}
|
|
134
|
+
} else if (isSectionName(desc)) {
|
|
135
|
+
result = [level, this.section(desc)];
|
|
136
|
+
debug('yield', result);
|
|
137
|
+
yield result;
|
|
138
|
+
} else if (isSetName(desc)) {
|
|
139
|
+
lTree = this.hSets[desc];
|
|
140
|
+
assert(defined(lTree), `Not a Set: ${OL(desc)}`);
|
|
141
|
+
yield* this.allSections(lTree, level);
|
|
142
|
+
} else {
|
|
143
|
+
croak(`Bad item: ${OL(desc)}`);
|
|
125
144
|
}
|
|
126
145
|
debug("return from allSections()");
|
|
127
146
|
}
|
|
128
147
|
|
|
129
148
|
// ..........................................................
|
|
130
|
-
|
|
131
|
-
var
|
|
132
|
-
debug("enter
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
assert(defined(this.hSections[secName]), `not a section name ${OL(secName)}`);
|
|
149
|
+
getBlock() {
|
|
150
|
+
var _, lParts, ref, result, sect, x;
|
|
151
|
+
debug("enter getBlock()");
|
|
152
|
+
lParts = [];
|
|
153
|
+
ref = this.allSections();
|
|
154
|
+
for (x of ref) {
|
|
155
|
+
[_, sect] = x;
|
|
156
|
+
if (sect.nonEmpty()) {
|
|
157
|
+
lParts.push(sect.getBlock());
|
|
158
|
+
}
|
|
141
159
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
debug("return from
|
|
160
|
+
debug('lParts', lParts);
|
|
161
|
+
result = arrayToBlock(lParts);
|
|
162
|
+
debug("return from getBlock()", result);
|
|
163
|
+
return result;
|
|
145
164
|
}
|
|
146
165
|
|
|
147
166
|
// ..........................................................
|
|
@@ -154,30 +173,31 @@ export var SectionMap = class SectionMap {
|
|
|
154
173
|
|
|
155
174
|
// ..........................................................
|
|
156
175
|
firstSection(name) {
|
|
157
|
-
var
|
|
176
|
+
var lSectionTree;
|
|
158
177
|
assert(isSetName(name), `bad set name ${OL(name)}`);
|
|
159
|
-
|
|
160
|
-
assert(defined(
|
|
161
|
-
assert(nonEmpty(
|
|
162
|
-
return this.section(
|
|
178
|
+
lSectionTree = this.hSets[name];
|
|
179
|
+
assert(defined(lSectionTree), `no such set ${OL(name)}`);
|
|
180
|
+
assert(nonEmpty(lSectionTree), `empty section ${OL(name)}`);
|
|
181
|
+
return this.section(lSectionTree[0]);
|
|
163
182
|
}
|
|
164
183
|
|
|
165
184
|
// ..........................................................
|
|
166
185
|
lastSection(name) {
|
|
167
|
-
var
|
|
186
|
+
var lSectionTree;
|
|
168
187
|
assert(isSetName(name), `bad set name ${OL(name)}`);
|
|
169
|
-
|
|
170
|
-
assert(defined(
|
|
171
|
-
assert(nonEmpty(
|
|
172
|
-
return this.section(
|
|
188
|
+
lSectionTree = this.hSets[name];
|
|
189
|
+
assert(defined(lSectionTree), `no such set ${OL(name)}`);
|
|
190
|
+
assert(nonEmpty(lSectionTree), `empty section ${OL(name)}`);
|
|
191
|
+
return this.section(lSectionTree[lSectionTree.length - 1]);
|
|
173
192
|
}
|
|
174
193
|
|
|
175
194
|
// ..........................................................
|
|
176
195
|
length(desc = undef) {
|
|
177
|
-
var ref, result, sect;
|
|
196
|
+
var _, ref, result, sect, x;
|
|
178
197
|
result = 0;
|
|
179
198
|
ref = this.allSections(desc);
|
|
180
|
-
for (
|
|
199
|
+
for (x of ref) {
|
|
200
|
+
[_, sect] = x;
|
|
181
201
|
result += sect.length();
|
|
182
202
|
}
|
|
183
203
|
return result;
|
|
@@ -195,9 +215,10 @@ export var SectionMap = class SectionMap {
|
|
|
195
215
|
|
|
196
216
|
// ..........................................................
|
|
197
217
|
indent(desc = undef, level = 1) {
|
|
198
|
-
var ref, sect;
|
|
218
|
+
var _, ref, sect, x;
|
|
199
219
|
ref = this.allSections(desc);
|
|
200
|
-
for (
|
|
220
|
+
for (x of ref) {
|
|
221
|
+
[_, sect] = x;
|
|
201
222
|
sect.indent(level);
|
|
202
223
|
}
|
|
203
224
|
}
|
|
@@ -224,34 +245,18 @@ export var SectionMap = class SectionMap {
|
|
|
224
245
|
}
|
|
225
246
|
|
|
226
247
|
// ..........................................................
|
|
227
|
-
|
|
228
|
-
var result;
|
|
229
|
-
debug("enter
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
debug("return from getBlock()", result);
|
|
236
|
-
return result;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// ..........................................................
|
|
240
|
-
accumBlock(tree) {
|
|
241
|
-
var block, i, len, subtree;
|
|
242
|
-
if (isString(tree)) {
|
|
243
|
-
debug(`accumBlock ${OL(tree)}`);
|
|
244
|
-
block = this.section(tree).getBlock();
|
|
245
|
-
if (nonEmpty(block)) {
|
|
246
|
-
this.lAllBlocks.push(block);
|
|
247
|
-
}
|
|
248
|
-
} else {
|
|
249
|
-
assert(isArray(tree), "not an array");
|
|
250
|
-
for (i = 0, len = tree.length; i < len; i++) {
|
|
251
|
-
subtree = tree[i];
|
|
252
|
-
this.accumBlock(subtree);
|
|
253
|
-
}
|
|
248
|
+
getShape() {
|
|
249
|
+
var lParts, level, ref, result, sect, x;
|
|
250
|
+
debug("enter getShape()");
|
|
251
|
+
lParts = [];
|
|
252
|
+
ref = this.allSections();
|
|
253
|
+
for (x of ref) {
|
|
254
|
+
[level, sect] = x;
|
|
255
|
+
lParts.push(indented(sect.name, level));
|
|
254
256
|
}
|
|
257
|
+
result = arrayToBlock(lParts);
|
|
258
|
+
debug("return from getShape()", result);
|
|
259
|
+
return result;
|
|
255
260
|
}
|
|
256
261
|
|
|
257
262
|
};
|
package/src/block_utils.coffee
CHANGED
|
@@ -30,19 +30,31 @@ export blockToArray = (block) ->
|
|
|
30
30
|
export arrayToBlock = (lLines) ->
|
|
31
31
|
|
|
32
32
|
if (lLines == undef)
|
|
33
|
-
return
|
|
33
|
+
return undef
|
|
34
34
|
assert isArray(lLines), "lLines is not an array"
|
|
35
35
|
lLines = lLines.filter((line) => defined(line));
|
|
36
36
|
if lLines.length == 0
|
|
37
|
-
return
|
|
37
|
+
return undef
|
|
38
38
|
else
|
|
39
39
|
return rtrim(lLines.join('\n'))
|
|
40
40
|
|
|
41
41
|
# ---------------------------------------------------------------------------
|
|
42
42
|
|
|
43
|
+
export splitBlock = (block) ->
|
|
44
|
+
|
|
45
|
+
assert isString(block), "not a string"
|
|
46
|
+
pos = block.indexOf('\n')
|
|
47
|
+
if (pos == -1)
|
|
48
|
+
return [block, undef]
|
|
49
|
+
else
|
|
50
|
+
return [block.substring(0, pos), block.substring(pos+1)]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# ---------------------------------------------------------------------------
|
|
54
|
+
|
|
43
55
|
export firstLine = (block) ->
|
|
44
56
|
|
|
45
|
-
assert isString(block), "
|
|
57
|
+
assert isString(block), "not a string"
|
|
46
58
|
pos = block.indexOf('\n')
|
|
47
59
|
if (pos == -1)
|
|
48
60
|
return block
|
|
@@ -53,10 +65,10 @@ export firstLine = (block) ->
|
|
|
53
65
|
|
|
54
66
|
export remainingLines = (block) ->
|
|
55
67
|
|
|
56
|
-
assert isString(block), "
|
|
68
|
+
assert isString(block), "not a string"
|
|
57
69
|
pos = block.indexOf('\n')
|
|
58
70
|
if (pos == -1)
|
|
59
|
-
return
|
|
71
|
+
return undef
|
|
60
72
|
else
|
|
61
73
|
return block.substring(pos+1)
|
|
62
74
|
|
package/src/block_utils.js
CHANGED
|
@@ -38,23 +38,35 @@ export var blockToArray = function(block) {
|
|
|
38
38
|
// arrayToBlock - block will have no trailing whitespace
|
|
39
39
|
export var arrayToBlock = function(lLines) {
|
|
40
40
|
if (lLines === undef) {
|
|
41
|
-
return
|
|
41
|
+
return undef;
|
|
42
42
|
}
|
|
43
43
|
assert(isArray(lLines), "lLines is not an array");
|
|
44
44
|
lLines = lLines.filter((line) => {
|
|
45
45
|
return defined(line);
|
|
46
46
|
});
|
|
47
47
|
if (lLines.length === 0) {
|
|
48
|
-
return
|
|
48
|
+
return undef;
|
|
49
49
|
} else {
|
|
50
50
|
return rtrim(lLines.join('\n'));
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
export var splitBlock = function(block) {
|
|
56
|
+
var pos;
|
|
57
|
+
assert(isString(block), "not a string");
|
|
58
|
+
pos = block.indexOf('\n');
|
|
59
|
+
if (pos === -1) {
|
|
60
|
+
return [block, undef];
|
|
61
|
+
} else {
|
|
62
|
+
return [block.substring(0, pos), block.substring(pos + 1)];
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
54
66
|
// ---------------------------------------------------------------------------
|
|
55
67
|
export var firstLine = function(block) {
|
|
56
68
|
var pos;
|
|
57
|
-
assert(isString(block), "
|
|
69
|
+
assert(isString(block), "not a string");
|
|
58
70
|
pos = block.indexOf('\n');
|
|
59
71
|
if (pos === -1) {
|
|
60
72
|
return block;
|
|
@@ -66,10 +78,10 @@ export var firstLine = function(block) {
|
|
|
66
78
|
// ---------------------------------------------------------------------------
|
|
67
79
|
export var remainingLines = function(block) {
|
|
68
80
|
var pos;
|
|
69
|
-
assert(isString(block), "
|
|
81
|
+
assert(isString(block), "not a string");
|
|
70
82
|
pos = block.indexOf('\n');
|
|
71
83
|
if (pos === -1) {
|
|
72
|
-
return
|
|
84
|
+
return undef;
|
|
73
85
|
} else {
|
|
74
86
|
return block.substring(pos + 1);
|
|
75
87
|
}
|