@jdeighan/coffee-utils 8.0.2 → 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 +4 -2
- package/src/Section.coffee +69 -0
- package/src/Section.js +85 -0
- package/src/SectionMap.coffee +221 -0
- package/src/SectionMap.js +262 -0
- package/src/block_utils.coffee +17 -5
- package/src/block_utils.js +17 -5
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jdeighan/coffee-utils",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "8.0.
|
|
4
|
+
"version": "8.0.5",
|
|
5
5
|
"description": "A set of utility functions for CoffeeScript",
|
|
6
6
|
"main": "coffee_utils.js",
|
|
7
7
|
"exports": {
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
"./store": "./src/DataStores.js",
|
|
20
20
|
"./taml": "./src/taml.js",
|
|
21
21
|
"./placeholders": "./src/placeholders.js",
|
|
22
|
+
"./section": "./src/Section.js",
|
|
23
|
+
"./sectionmap": "./src/SectionMap.js",
|
|
22
24
|
"./package.json": "./package.json"
|
|
23
25
|
},
|
|
24
26
|
"engines": {
|
|
@@ -53,6 +55,6 @@
|
|
|
53
55
|
"svelte": "^3.48.0"
|
|
54
56
|
},
|
|
55
57
|
"devDependencies": {
|
|
56
|
-
"@jdeighan/unit-tester": "^2.0.
|
|
58
|
+
"@jdeighan/unit-tester": "^2.0.9"
|
|
57
59
|
}
|
|
58
60
|
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Section.coffee
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
assert, pass, undef, defined, croak, isArray,
|
|
5
|
+
} from '@jdeighan/coffee-utils'
|
|
6
|
+
import {arrayToBlock} from '@jdeighan/coffee-utils/block'
|
|
7
|
+
import {indented} from '@jdeighan/coffee-utils/indent'
|
|
8
|
+
|
|
9
|
+
# ---------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
export class Section
|
|
12
|
+
|
|
13
|
+
constructor: (@name) ->
|
|
14
|
+
|
|
15
|
+
@lLines = []
|
|
16
|
+
|
|
17
|
+
# ..........................................................
|
|
18
|
+
|
|
19
|
+
length: () ->
|
|
20
|
+
|
|
21
|
+
return @lLines.length
|
|
22
|
+
|
|
23
|
+
# ..........................................................
|
|
24
|
+
|
|
25
|
+
indent: (level=1) ->
|
|
26
|
+
|
|
27
|
+
lNewLines = for line in @lLines
|
|
28
|
+
indented(line, level)
|
|
29
|
+
@lLines = lNewLines
|
|
30
|
+
return
|
|
31
|
+
|
|
32
|
+
# ..........................................................
|
|
33
|
+
|
|
34
|
+
isEmpty: () ->
|
|
35
|
+
|
|
36
|
+
return (@lLines.length == 0)
|
|
37
|
+
|
|
38
|
+
# ..........................................................
|
|
39
|
+
|
|
40
|
+
nonEmpty: () ->
|
|
41
|
+
|
|
42
|
+
return (@lLines.length > 0)
|
|
43
|
+
|
|
44
|
+
# ..........................................................
|
|
45
|
+
|
|
46
|
+
add: (data) ->
|
|
47
|
+
|
|
48
|
+
if isArray(data)
|
|
49
|
+
for line in data
|
|
50
|
+
@lLines.push line
|
|
51
|
+
else
|
|
52
|
+
@lLines.push data
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
# ..........................................................
|
|
56
|
+
|
|
57
|
+
prepend: (data) ->
|
|
58
|
+
|
|
59
|
+
if isArray(data)
|
|
60
|
+
@lLines = [data..., @lLines...]
|
|
61
|
+
else
|
|
62
|
+
@lLines = [data, @lLines...]
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
# ..........................................................
|
|
66
|
+
|
|
67
|
+
getBlock: () ->
|
|
68
|
+
|
|
69
|
+
return arrayToBlock(@lLines)
|
package/src/Section.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Generated by CoffeeScript 2.7.0
|
|
2
|
+
// Section.coffee
|
|
3
|
+
import {
|
|
4
|
+
assert,
|
|
5
|
+
pass,
|
|
6
|
+
undef,
|
|
7
|
+
defined,
|
|
8
|
+
croak,
|
|
9
|
+
isArray
|
|
10
|
+
} from '@jdeighan/coffee-utils';
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
arrayToBlock
|
|
14
|
+
} from '@jdeighan/coffee-utils/block';
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
indented
|
|
18
|
+
} from '@jdeighan/coffee-utils/indent';
|
|
19
|
+
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
export var Section = class Section {
|
|
22
|
+
constructor(name) {
|
|
23
|
+
this.name = name;
|
|
24
|
+
this.lLines = [];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// ..........................................................
|
|
28
|
+
length() {
|
|
29
|
+
return this.lLines.length;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ..........................................................
|
|
33
|
+
indent(level = 1) {
|
|
34
|
+
var lNewLines, line;
|
|
35
|
+
lNewLines = (function() {
|
|
36
|
+
var i, len, ref, results;
|
|
37
|
+
ref = this.lLines;
|
|
38
|
+
results = [];
|
|
39
|
+
for (i = 0, len = ref.length; i < len; i++) {
|
|
40
|
+
line = ref[i];
|
|
41
|
+
results.push(indented(line, level));
|
|
42
|
+
}
|
|
43
|
+
return results;
|
|
44
|
+
}).call(this);
|
|
45
|
+
this.lLines = lNewLines;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ..........................................................
|
|
49
|
+
isEmpty() {
|
|
50
|
+
return this.lLines.length === 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// ..........................................................
|
|
54
|
+
nonEmpty() {
|
|
55
|
+
return this.lLines.length > 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ..........................................................
|
|
59
|
+
add(data) {
|
|
60
|
+
var i, len, line;
|
|
61
|
+
if (isArray(data)) {
|
|
62
|
+
for (i = 0, len = data.length; i < len; i++) {
|
|
63
|
+
line = data[i];
|
|
64
|
+
this.lLines.push(line);
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
this.lLines.push(data);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ..........................................................
|
|
72
|
+
prepend(data) {
|
|
73
|
+
if (isArray(data)) {
|
|
74
|
+
this.lLines = [...data, ...this.lLines];
|
|
75
|
+
} else {
|
|
76
|
+
this.lLines = [data, ...this.lLines];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ..........................................................
|
|
81
|
+
getBlock() {
|
|
82
|
+
return arrayToBlock(this.lLines);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
};
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# SectionMap.coffee
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
assert, pass, undef, defined, croak, OL, isEmpty, nonEmpty,
|
|
5
|
+
isString, isHash, isArray, isUniqueTree, isNonEmptyString,
|
|
6
|
+
} from '@jdeighan/coffee-utils'
|
|
7
|
+
import {arrayToBlock} from '@jdeighan/coffee-utils/block'
|
|
8
|
+
import {indented} from '@jdeighan/coffee-utils/indent'
|
|
9
|
+
import {debug} from '@jdeighan/coffee-utils/debug'
|
|
10
|
+
import {Section} from '@jdeighan/coffee-utils/section'
|
|
11
|
+
|
|
12
|
+
# ---------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
isSectionName = (name) ->
|
|
15
|
+
|
|
16
|
+
return isString(name) && name.match(/^[a-z][a-z0-9]*/)
|
|
17
|
+
|
|
18
|
+
# ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
isSetName = (name) ->
|
|
21
|
+
|
|
22
|
+
return isString(name) && name.match(/^[A-Z][a-z0-9]*/)
|
|
23
|
+
|
|
24
|
+
# ---------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
export class SectionMap
|
|
27
|
+
|
|
28
|
+
constructor: (lSectionTree) ->
|
|
29
|
+
# --- lSectionTree is a tree of section names
|
|
30
|
+
|
|
31
|
+
debug "enter SectionMap()", lSectionTree
|
|
32
|
+
@lSectionTree = lSectionTree # a tree of section names
|
|
33
|
+
@hSets = {}
|
|
34
|
+
@hSections = {}
|
|
35
|
+
@addSections lSectionTree
|
|
36
|
+
debug "return from SectionMap()", @hSections
|
|
37
|
+
|
|
38
|
+
# ..........................................................
|
|
39
|
+
|
|
40
|
+
addSections: (desc) ->
|
|
41
|
+
# --- returns a flat array of sections that were added
|
|
42
|
+
|
|
43
|
+
if isString(desc)
|
|
44
|
+
assert nonEmpty(desc), "empty section name"
|
|
45
|
+
assert isSectionName(desc), "bad section name #{OL(desc)}"
|
|
46
|
+
assert (@hSections[desc] == undef), "duplicate section #{OL(desc)}"
|
|
47
|
+
@hSections[desc] = new Section(desc)
|
|
48
|
+
return [desc]
|
|
49
|
+
else
|
|
50
|
+
assert isArray(desc), "not an array or string #{OL(desc)}"
|
|
51
|
+
name = undef
|
|
52
|
+
lParts = []
|
|
53
|
+
for item,i in desc
|
|
54
|
+
if (i==0) && isSetName(item)
|
|
55
|
+
name = item
|
|
56
|
+
else
|
|
57
|
+
lAdded = @addSections item
|
|
58
|
+
for item in lAdded
|
|
59
|
+
lParts.push item
|
|
60
|
+
if defined(name)
|
|
61
|
+
@addSet name, lParts
|
|
62
|
+
return lParts
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
# ..........................................................
|
|
66
|
+
|
|
67
|
+
addSet: (name, lSectionTree) ->
|
|
68
|
+
|
|
69
|
+
debug "enter addSet()", name, lSectionTree
|
|
70
|
+
|
|
71
|
+
# --- check the name
|
|
72
|
+
assert isSetName(name), "not a valid set name #{OL(name)}"
|
|
73
|
+
|
|
74
|
+
# --- check lSectionTree
|
|
75
|
+
assert isArray(lSectionTree), "arg 2 not an array"
|
|
76
|
+
for secName in lSectionTree
|
|
77
|
+
assert isNonEmptyString(secName),
|
|
78
|
+
"not a non-empty string #{OL(secName)}"
|
|
79
|
+
assert defined(@hSections[secName]),
|
|
80
|
+
"not a section name #{OL(secName)}"
|
|
81
|
+
|
|
82
|
+
@hSets[name] = lSectionTree
|
|
83
|
+
debug 'hSets', @hSets
|
|
84
|
+
debug "return from addSet()"
|
|
85
|
+
return
|
|
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
|
+
|
|
135
|
+
# ..........................................................
|
|
136
|
+
|
|
137
|
+
section: (name) ->
|
|
138
|
+
|
|
139
|
+
sect = @hSections[name]
|
|
140
|
+
assert defined(sect), "No section named #{OL(name)}"
|
|
141
|
+
return sect
|
|
142
|
+
|
|
143
|
+
# ..........................................................
|
|
144
|
+
|
|
145
|
+
firstSection: (name) ->
|
|
146
|
+
|
|
147
|
+
assert isSetName(name), "bad set name #{OL(name)}"
|
|
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])
|
|
152
|
+
|
|
153
|
+
# ..........................................................
|
|
154
|
+
|
|
155
|
+
lastSection: (name) ->
|
|
156
|
+
|
|
157
|
+
assert isSetName(name), "bad set name #{OL(name)}"
|
|
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])
|
|
162
|
+
|
|
163
|
+
# ..........................................................
|
|
164
|
+
|
|
165
|
+
length: (desc=undef) ->
|
|
166
|
+
|
|
167
|
+
result = 0
|
|
168
|
+
for [_, sect] from @allSections(desc)
|
|
169
|
+
result += sect.length()
|
|
170
|
+
return result
|
|
171
|
+
|
|
172
|
+
# ..........................................................
|
|
173
|
+
|
|
174
|
+
isEmpty: (desc=undef) ->
|
|
175
|
+
|
|
176
|
+
return (@length(desc) == 0)
|
|
177
|
+
|
|
178
|
+
# ..........................................................
|
|
179
|
+
|
|
180
|
+
nonEmpty: (desc=undef) ->
|
|
181
|
+
|
|
182
|
+
return (@length(desc) > 0)
|
|
183
|
+
|
|
184
|
+
# ..........................................................
|
|
185
|
+
|
|
186
|
+
indent: (desc=undef, level=1) ->
|
|
187
|
+
|
|
188
|
+
for [_, sect] from @allSections(desc)
|
|
189
|
+
sect.indent(level)
|
|
190
|
+
return
|
|
191
|
+
|
|
192
|
+
# ..........................................................
|
|
193
|
+
|
|
194
|
+
enclose: (name, pre, post) ->
|
|
195
|
+
|
|
196
|
+
if isSectionName(name)
|
|
197
|
+
sect = @section(name)
|
|
198
|
+
if sect.nonEmpty()
|
|
199
|
+
sect.indent()
|
|
200
|
+
sect.prepend(pre)
|
|
201
|
+
sect.add(post)
|
|
202
|
+
else if isSetName(name)
|
|
203
|
+
if @nonEmpty(name)
|
|
204
|
+
@indent(name)
|
|
205
|
+
@firstSection(name).prepend(pre)
|
|
206
|
+
@lastSection(name).add(post)
|
|
207
|
+
else
|
|
208
|
+
croak "Bad name param #{OL(name)}"
|
|
209
|
+
return
|
|
210
|
+
|
|
211
|
+
# ..........................................................
|
|
212
|
+
|
|
213
|
+
getShape: () ->
|
|
214
|
+
|
|
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
|
|
221
|
+
return result
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
// Generated by CoffeeScript 2.7.0
|
|
2
|
+
// SectionMap.coffee
|
|
3
|
+
var isSectionName, isSetName;
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
assert,
|
|
7
|
+
pass,
|
|
8
|
+
undef,
|
|
9
|
+
defined,
|
|
10
|
+
croak,
|
|
11
|
+
OL,
|
|
12
|
+
isEmpty,
|
|
13
|
+
nonEmpty,
|
|
14
|
+
isString,
|
|
15
|
+
isHash,
|
|
16
|
+
isArray,
|
|
17
|
+
isUniqueTree,
|
|
18
|
+
isNonEmptyString
|
|
19
|
+
} from '@jdeighan/coffee-utils';
|
|
20
|
+
|
|
21
|
+
import {
|
|
22
|
+
arrayToBlock
|
|
23
|
+
} from '@jdeighan/coffee-utils/block';
|
|
24
|
+
|
|
25
|
+
import {
|
|
26
|
+
indented
|
|
27
|
+
} from '@jdeighan/coffee-utils/indent';
|
|
28
|
+
|
|
29
|
+
import {
|
|
30
|
+
debug
|
|
31
|
+
} from '@jdeighan/coffee-utils/debug';
|
|
32
|
+
|
|
33
|
+
import {
|
|
34
|
+
Section
|
|
35
|
+
} from '@jdeighan/coffee-utils/section';
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
isSectionName = function(name) {
|
|
39
|
+
return isString(name) && name.match(/^[a-z][a-z0-9]*/);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
isSetName = function(name) {
|
|
44
|
+
return isString(name) && name.match(/^[A-Z][a-z0-9]*/);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
export var SectionMap = class SectionMap {
|
|
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
|
|
53
|
+
this.hSets = {};
|
|
54
|
+
this.hSections = {};
|
|
55
|
+
this.addSections(lSectionTree);
|
|
56
|
+
debug("return from SectionMap()", this.hSections);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ..........................................................
|
|
60
|
+
addSections(desc) {
|
|
61
|
+
var i, item, j, k, lAdded, lParts, len, len1, name;
|
|
62
|
+
// --- returns a flat array of sections that were added
|
|
63
|
+
if (isString(desc)) {
|
|
64
|
+
assert(nonEmpty(desc), "empty section name");
|
|
65
|
+
assert(isSectionName(desc), `bad section name ${OL(desc)}`);
|
|
66
|
+
assert(this.hSections[desc] === undef, `duplicate section ${OL(desc)}`);
|
|
67
|
+
this.hSections[desc] = new Section(desc);
|
|
68
|
+
return [desc];
|
|
69
|
+
} else {
|
|
70
|
+
assert(isArray(desc), `not an array or string ${OL(desc)}`);
|
|
71
|
+
name = undef;
|
|
72
|
+
lParts = [];
|
|
73
|
+
for (i = j = 0, len = desc.length; j < len; i = ++j) {
|
|
74
|
+
item = desc[i];
|
|
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
|
+
}
|
|
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)}`);
|
|
104
|
+
}
|
|
105
|
+
this.hSets[name] = lSectionTree;
|
|
106
|
+
debug('hSets', this.hSets);
|
|
107
|
+
debug("return from addSet()");
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// ..........................................................
|
|
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);
|
|
117
|
+
if (desc === undef) {
|
|
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;
|
|
129
|
+
} else {
|
|
130
|
+
assert(isArray(item), `not an array ${OL(item)}`);
|
|
131
|
+
yield* this.allSections(item, level + 1);
|
|
132
|
+
}
|
|
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)}`);
|
|
144
|
+
}
|
|
145
|
+
debug("return from allSections()");
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ..........................................................
|
|
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
|
+
}
|
|
159
|
+
}
|
|
160
|
+
debug('lParts', lParts);
|
|
161
|
+
result = arrayToBlock(lParts);
|
|
162
|
+
debug("return from getBlock()", result);
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ..........................................................
|
|
167
|
+
section(name) {
|
|
168
|
+
var sect;
|
|
169
|
+
sect = this.hSections[name];
|
|
170
|
+
assert(defined(sect), `No section named ${OL(name)}`);
|
|
171
|
+
return sect;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ..........................................................
|
|
175
|
+
firstSection(name) {
|
|
176
|
+
var lSectionTree;
|
|
177
|
+
assert(isSetName(name), `bad set name ${OL(name)}`);
|
|
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]);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// ..........................................................
|
|
185
|
+
lastSection(name) {
|
|
186
|
+
var lSectionTree;
|
|
187
|
+
assert(isSetName(name), `bad set name ${OL(name)}`);
|
|
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]);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ..........................................................
|
|
195
|
+
length(desc = undef) {
|
|
196
|
+
var _, ref, result, sect, x;
|
|
197
|
+
result = 0;
|
|
198
|
+
ref = this.allSections(desc);
|
|
199
|
+
for (x of ref) {
|
|
200
|
+
[_, sect] = x;
|
|
201
|
+
result += sect.length();
|
|
202
|
+
}
|
|
203
|
+
return result;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// ..........................................................
|
|
207
|
+
isEmpty(desc = undef) {
|
|
208
|
+
return this.length(desc) === 0;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ..........................................................
|
|
212
|
+
nonEmpty(desc = undef) {
|
|
213
|
+
return this.length(desc) > 0;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ..........................................................
|
|
217
|
+
indent(desc = undef, level = 1) {
|
|
218
|
+
var _, ref, sect, x;
|
|
219
|
+
ref = this.allSections(desc);
|
|
220
|
+
for (x of ref) {
|
|
221
|
+
[_, sect] = x;
|
|
222
|
+
sect.indent(level);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// ..........................................................
|
|
227
|
+
enclose(name, pre, post) {
|
|
228
|
+
var sect;
|
|
229
|
+
if (isSectionName(name)) {
|
|
230
|
+
sect = this.section(name);
|
|
231
|
+
if (sect.nonEmpty()) {
|
|
232
|
+
sect.indent();
|
|
233
|
+
sect.prepend(pre);
|
|
234
|
+
sect.add(post);
|
|
235
|
+
}
|
|
236
|
+
} else if (isSetName(name)) {
|
|
237
|
+
if (this.nonEmpty(name)) {
|
|
238
|
+
this.indent(name);
|
|
239
|
+
this.firstSection(name).prepend(pre);
|
|
240
|
+
this.lastSection(name).add(post);
|
|
241
|
+
}
|
|
242
|
+
} else {
|
|
243
|
+
croak(`Bad name param ${OL(name)}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// ..........................................................
|
|
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));
|
|
256
|
+
}
|
|
257
|
+
result = arrayToBlock(lParts);
|
|
258
|
+
debug("return from getShape()", result);
|
|
259
|
+
return result;
|
|
260
|
+
}
|
|
261
|
+
|
|
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
|
}
|