@jdeighan/coffee-utils 11.0.30 → 11.0.32
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 -6
- package/src/Section.coffee +10 -25
- package/src/Section.js +14 -35
- package/src/SectionMap.coffee +160 -110
- package/src/SectionMap.js +190 -137
- package/src/block.coffee +2 -1
- package/src/block.js +1 -1
- package/src/fs.coffee +3 -1
- package/src/fs.js +3 -0
- package/src/utils.coffee +8 -3
- package/src/utils.js +11 -4
- package/src/placeholders.coffee +0 -26
- package/src/placeholders.js +0 -34
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jdeighan/coffee-utils",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "11.0.
|
|
4
|
+
"version": "11.0.32",
|
|
5
5
|
"description": "A set of utility functions for CoffeeScript",
|
|
6
6
|
"main": "coffee_utils.js",
|
|
7
7
|
"exports": {
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"./svelte": "./src/svelte.js",
|
|
20
20
|
"./store": "./src/DataStores.js",
|
|
21
21
|
"./taml": "./src/taml.js",
|
|
22
|
-
"./placeholders": "./src/placeholders.js",
|
|
23
22
|
"./section": "./src/Section.js",
|
|
24
23
|
"./sectionmap": "./src/SectionMap.js",
|
|
25
24
|
"./fsa": "./src/fsa.js",
|
|
@@ -32,8 +31,7 @@
|
|
|
32
31
|
"verbose": false
|
|
33
32
|
},
|
|
34
33
|
"scripts": {
|
|
35
|
-
"build": "cls &&
|
|
36
|
-
"pretest": "cls && cielo -qfc ./test && coffee -c .",
|
|
34
|
+
"build": "cls && coffee -c .",
|
|
37
35
|
"test": "npm run build && ava ./test/*.test.js && git status"
|
|
38
36
|
},
|
|
39
37
|
"repository": {
|
|
@@ -50,7 +48,7 @@
|
|
|
50
48
|
},
|
|
51
49
|
"homepage": "https://github.com/johndeighan/coffee-utils#readme",
|
|
52
50
|
"dependencies": {
|
|
53
|
-
"@jdeighan/exceptions": "^1.0.
|
|
51
|
+
"@jdeighan/exceptions": "^1.0.26",
|
|
54
52
|
"cross-env": "^7.0.3",
|
|
55
53
|
"js-yaml": "^4.1.0",
|
|
56
54
|
"n-readlines": "^1.0.1",
|
|
@@ -58,6 +56,6 @@
|
|
|
58
56
|
"svelte": "^3.52.0"
|
|
59
57
|
},
|
|
60
58
|
"devDependencies": {
|
|
61
|
-
"@jdeighan/unit-tester": "^2.0.
|
|
59
|
+
"@jdeighan/unit-tester": "^2.0.52"
|
|
62
60
|
}
|
|
63
61
|
}
|
package/src/Section.coffee
CHANGED
|
@@ -3,36 +3,20 @@
|
|
|
3
3
|
import {assert, croak} from '@jdeighan/exceptions'
|
|
4
4
|
import {debug} from '@jdeighan/exceptions/debug'
|
|
5
5
|
import {
|
|
6
|
-
pass, undef, defined, isArray, isEmpty,
|
|
6
|
+
pass, undef, defined, isArray, isEmpty, isFunction,
|
|
7
7
|
} from '@jdeighan/coffee-utils'
|
|
8
|
-
import {
|
|
9
|
-
import {indented} from '@jdeighan/coffee-utils/indent'
|
|
8
|
+
import {toBlock} from '@jdeighan/coffee-utils/block'
|
|
10
9
|
|
|
11
10
|
# ---------------------------------------------------------------------------
|
|
12
11
|
|
|
13
12
|
export class Section
|
|
14
13
|
|
|
15
|
-
constructor: (@name,
|
|
14
|
+
constructor: (@name, @replacer=undef) ->
|
|
16
15
|
# --- name can be undef or empty
|
|
17
16
|
|
|
18
17
|
@lParts = []
|
|
19
|
-
if defined(
|
|
20
|
-
@
|
|
21
|
-
|
|
22
|
-
# ..........................................................
|
|
23
|
-
|
|
24
|
-
length: () ->
|
|
25
|
-
|
|
26
|
-
return @lParts.length
|
|
27
|
-
|
|
28
|
-
# ..........................................................
|
|
29
|
-
|
|
30
|
-
indent: (level=1, oneIndent="\t") ->
|
|
31
|
-
|
|
32
|
-
lNewLines = for line in @lParts
|
|
33
|
-
indented(line, level, oneIndent)
|
|
34
|
-
@lParts = lNewLines
|
|
35
|
-
return
|
|
18
|
+
if defined(@replacer)
|
|
19
|
+
assert isFunction(@replacer), "bad replacer"
|
|
36
20
|
|
|
37
21
|
# ..........................................................
|
|
38
22
|
|
|
@@ -81,7 +65,8 @@ export class Section
|
|
|
81
65
|
if (@lParts.length == 0)
|
|
82
66
|
debug "return undef from Section.getBlock()"
|
|
83
67
|
return undef
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
68
|
+
block = toBlock(@lParts)
|
|
69
|
+
if defined(@replacer)
|
|
70
|
+
block = @replacer block
|
|
71
|
+
debug "return from Section.getBlock()", block
|
|
72
|
+
return block
|
package/src/Section.js
CHANGED
|
@@ -14,49 +14,26 @@ import {
|
|
|
14
14
|
undef,
|
|
15
15
|
defined,
|
|
16
16
|
isArray,
|
|
17
|
-
isEmpty
|
|
17
|
+
isEmpty,
|
|
18
|
+
isFunction
|
|
18
19
|
} from '@jdeighan/coffee-utils';
|
|
19
20
|
|
|
20
21
|
import {
|
|
21
|
-
|
|
22
|
+
toBlock
|
|
22
23
|
} from '@jdeighan/coffee-utils/block';
|
|
23
24
|
|
|
24
|
-
import {
|
|
25
|
-
indented
|
|
26
|
-
} from '@jdeighan/coffee-utils/indent';
|
|
27
|
-
|
|
28
25
|
// ---------------------------------------------------------------------------
|
|
29
26
|
export var Section = class Section {
|
|
30
|
-
constructor(name,
|
|
27
|
+
constructor(name, replacer = undef) {
|
|
31
28
|
this.name = name;
|
|
29
|
+
this.replacer = replacer;
|
|
32
30
|
// --- name can be undef or empty
|
|
33
31
|
this.lParts = [];
|
|
34
|
-
if (defined(
|
|
35
|
-
this.
|
|
32
|
+
if (defined(this.replacer)) {
|
|
33
|
+
assert(isFunction(this.replacer), "bad replacer");
|
|
36
34
|
}
|
|
37
35
|
}
|
|
38
36
|
|
|
39
|
-
// ..........................................................
|
|
40
|
-
length() {
|
|
41
|
-
return this.lParts.length;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// ..........................................................
|
|
45
|
-
indent(level = 1, oneIndent = "\t") {
|
|
46
|
-
var lNewLines, line;
|
|
47
|
-
lNewLines = (function() {
|
|
48
|
-
var i, len, ref, results;
|
|
49
|
-
ref = this.lParts;
|
|
50
|
-
results = [];
|
|
51
|
-
for (i = 0, len = ref.length; i < len; i++) {
|
|
52
|
-
line = ref[i];
|
|
53
|
-
results.push(indented(line, level, oneIndent));
|
|
54
|
-
}
|
|
55
|
-
return results;
|
|
56
|
-
}).call(this);
|
|
57
|
-
this.lParts = lNewLines;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
37
|
// ..........................................................
|
|
61
38
|
isEmpty() {
|
|
62
39
|
return this.lParts.length === 0;
|
|
@@ -96,16 +73,18 @@ export var Section = class Section {
|
|
|
96
73
|
|
|
97
74
|
// ..........................................................
|
|
98
75
|
getBlock() {
|
|
99
|
-
var
|
|
76
|
+
var block;
|
|
100
77
|
debug("enter Section.getBlock()");
|
|
101
78
|
if (this.lParts.length === 0) {
|
|
102
79
|
debug("return undef from Section.getBlock()");
|
|
103
80
|
return undef;
|
|
104
|
-
} else {
|
|
105
|
-
result = arrayToBlock(this.lParts);
|
|
106
|
-
debug("return from Section.getBlock()", result);
|
|
107
|
-
return result;
|
|
108
81
|
}
|
|
82
|
+
block = toBlock(this.lParts);
|
|
83
|
+
if (defined(this.replacer)) {
|
|
84
|
+
block = this.replacer(block);
|
|
85
|
+
}
|
|
86
|
+
debug("return from Section.getBlock()", block);
|
|
87
|
+
return block;
|
|
109
88
|
}
|
|
110
89
|
|
|
111
90
|
};
|
package/src/SectionMap.coffee
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
# SectionMap.coffee
|
|
2
2
|
|
|
3
|
-
import {assert, croak} from '@jdeighan/exceptions'
|
|
4
|
-
import {LOG} from '@jdeighan/exceptions/log'
|
|
5
|
-
import {debug} from '@jdeighan/exceptions/debug'
|
|
6
3
|
import {
|
|
7
|
-
|
|
4
|
+
assert, croak, LOG, LOGVALUE, LOGTAML, debug, isTAML, fromTAML,
|
|
5
|
+
} from '@jdeighan/exceptions'
|
|
6
|
+
import {
|
|
7
|
+
pass, undef, def, notdef, OL, isEmpty, nonEmpty,
|
|
8
8
|
isString, isHash, isArray, isUniqueTree, isNonEmptyString,
|
|
9
|
-
isNonEmptyArray,
|
|
9
|
+
isNonEmptyArray, isFunction, jsType, isArrayOfStrings,
|
|
10
10
|
} from '@jdeighan/coffee-utils'
|
|
11
11
|
import {toBlock} from '@jdeighan/coffee-utils/block'
|
|
12
|
-
import {isTAML, fromTAML} from '@jdeighan/coffee-utils/taml'
|
|
13
12
|
import {Section} from '@jdeighan/coffee-utils/section'
|
|
14
13
|
|
|
15
14
|
# ---------------------------------------------------------------------------
|
|
@@ -28,142 +27,161 @@ isSetName = (name) ->
|
|
|
28
27
|
|
|
29
28
|
export class SectionMap
|
|
30
29
|
|
|
31
|
-
constructor: (@
|
|
32
|
-
# ---
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
constructor: (tree, @hReplacers={}) ->
|
|
31
|
+
# --- tree is a tree of section/set names
|
|
32
|
+
# or a TAML string that converts to one
|
|
33
|
+
# --- hReplacers are callbacks that are called
|
|
34
|
+
# when a set or section is processed
|
|
35
|
+
# should be <name> -> <function>
|
|
36
|
+
# <name> can be a section name or a set name
|
|
37
|
+
# <function> should be <block> -> <block>
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
@SectionTree = fromTAML(@lSectionTree)
|
|
39
|
+
debug "enter SectionMap()", tree, @hReplacers
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
@checkTree tree
|
|
42
|
+
@checkReplacers @hReplacers
|
|
40
43
|
|
|
41
|
-
# ---
|
|
42
|
-
@
|
|
44
|
+
@hSections = {} # --- {section name: Section Object}
|
|
45
|
+
@hSets = {ALL: @lFullTree} # --- {set name: array of parts}
|
|
43
46
|
|
|
44
|
-
|
|
45
|
-
@hSets = {}
|
|
47
|
+
@init @lFullTree
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
debug
|
|
49
|
+
debug 'hSections', @hSections
|
|
50
|
+
debug 'hSets', @hSets
|
|
51
|
+
debug "return from SectionMap()"
|
|
49
52
|
|
|
50
53
|
# ..........................................................
|
|
51
54
|
|
|
52
|
-
|
|
55
|
+
init: (lTree) ->
|
|
53
56
|
|
|
54
|
-
debug "enter
|
|
57
|
+
debug "enter init()", lTree
|
|
55
58
|
assert isArray(lTree), "not an array"
|
|
56
59
|
assert nonEmpty(lTree), "empty array"
|
|
57
60
|
|
|
58
61
|
firstItem = lTree[0]
|
|
59
62
|
if isSetName(firstItem)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
@hSections[item] = new Section(item)
|
|
75
|
-
else
|
|
76
|
-
croak "Bad section tree: #{OL(@lSectionTree)}"
|
|
77
|
-
debug "return from build()", @hSections, @hSets
|
|
63
|
+
debug "found set name #{OL(firstItem)}"
|
|
64
|
+
lTree = lTree.slice(1)
|
|
65
|
+
@mkSet firstItem, lTree
|
|
66
|
+
|
|
67
|
+
for item in lTree
|
|
68
|
+
if isArray(item)
|
|
69
|
+
debug "init subtree"
|
|
70
|
+
@init item
|
|
71
|
+
else if isSectionName(item)
|
|
72
|
+
debug "mkSection #{OL(item)}"
|
|
73
|
+
@mkSection item
|
|
74
|
+
else
|
|
75
|
+
assert isString(item), "Bad item in tree: #{OL(item)}"
|
|
76
|
+
debug "return from init()"
|
|
78
77
|
return
|
|
79
78
|
|
|
80
79
|
# ..........................................................
|
|
81
|
-
# --- hProc should be <name> -> <function>
|
|
82
|
-
# <name> can be a section name or a set name
|
|
83
|
-
# <function> should be <block> -> <block>
|
|
84
|
-
# --- desc can be:
|
|
85
|
-
# an array, which may begin with a set name
|
|
86
|
-
# a section name
|
|
87
|
-
# a set name
|
|
88
|
-
# undef (equivalent to being set to @SectionTree)
|
|
89
|
-
|
|
90
|
-
getBlock: (desc=undef, hReplacers={}) ->
|
|
91
|
-
|
|
92
|
-
debug "enter SectionMap.getBlock()", desc, hReplacers
|
|
93
|
-
|
|
94
|
-
# --- desc can only be a string or an array
|
|
95
|
-
# so, if it's a hash, then it's really the hReplacers
|
|
96
|
-
# and the real desc is undef
|
|
97
|
-
|
|
98
|
-
if isHash(desc)
|
|
99
|
-
debug "arg 1 is hReplacers, no desc"
|
|
100
|
-
assert isEmpty(hReplacers), "invalid parms"
|
|
101
|
-
hReplacers = desc
|
|
102
|
-
desc = @lSectionTree
|
|
103
|
-
else if notdefined(desc)
|
|
104
|
-
debug "desc is entire tree"
|
|
105
|
-
desc = @lSectionTree
|
|
106
|
-
|
|
107
|
-
if isArray(desc)
|
|
108
|
-
debug "item is an array"
|
|
109
|
-
lBlocks = []
|
|
110
|
-
setName = undef
|
|
111
|
-
for item in desc
|
|
112
|
-
subBlock = undef
|
|
113
|
-
if isSetName(item)
|
|
114
|
-
debug "set name is #{item}"
|
|
115
|
-
setName = item
|
|
116
|
-
else if isSectionName(item) || isArray(item)
|
|
117
|
-
subBlock = @getBlock(item, hReplacers)
|
|
118
|
-
if defined(subBlock)
|
|
119
|
-
debug "add subBlock", subBlock
|
|
120
|
-
lBlocks.push subBlock
|
|
121
|
-
else
|
|
122
|
-
debug "subBlock is undef"
|
|
123
|
-
else if isString(item) && nonEmpty(item)
|
|
124
|
-
debug "add string", item
|
|
125
|
-
lBlocks.push item
|
|
126
|
-
else
|
|
127
|
-
croak "Bad item: #{OL(item)}"
|
|
128
80
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
81
|
+
mkSet: (name, lTree) ->
|
|
82
|
+
|
|
83
|
+
assert isArray(lTree), "tree is not an array"
|
|
84
|
+
assert nonEmpty(lTree), "set without sections"
|
|
85
|
+
assert notdef(@hSets[name]), "set #{OL(name)} already exists"
|
|
86
|
+
@hSets[name] = lTree
|
|
87
|
+
return
|
|
88
|
+
|
|
89
|
+
# ..........................................................
|
|
90
|
+
|
|
91
|
+
mkSection: (name) ->
|
|
92
|
+
|
|
93
|
+
assert notdef(@hSections[name]), "duplicate section name"
|
|
94
|
+
@hSections[name] = new Section(name, @hReplacers[name])
|
|
95
|
+
return
|
|
96
|
+
|
|
97
|
+
# ..........................................................
|
|
98
|
+
|
|
99
|
+
getBlock: (desc='ALL') ->
|
|
100
|
+
# ..........................................................
|
|
101
|
+
# --- desc can be:
|
|
102
|
+
# a section name
|
|
103
|
+
# a set name
|
|
104
|
+
# an array of section or set names or literal strings
|
|
105
|
+
# i.e. it should NOT contain sub-arrays
|
|
106
|
+
|
|
107
|
+
if isString(desc)
|
|
108
|
+
debug "enter SectionMap.getBlock(#{OL(desc)})"
|
|
109
|
+
else if isArrayOfStrings(desc)
|
|
110
|
+
debug "enter SectionMap.getBlock()", desc
|
|
111
|
+
else
|
|
112
|
+
croak "Bad desc: #{OL(desc)}"
|
|
113
|
+
|
|
114
|
+
if isSectionName(desc)
|
|
138
115
|
debug "item is a section name"
|
|
116
|
+
# --- a section's getBlock() applies any replacer
|
|
139
117
|
block = @section(desc).getBlock()
|
|
140
|
-
if defined(proc = hReplacers[desc])
|
|
141
|
-
debug "REPLACE #{desc}"
|
|
142
|
-
block = proc(block)
|
|
143
|
-
else
|
|
144
|
-
debug "NO REPLACER for #{desc}"
|
|
145
118
|
else if isSetName(desc)
|
|
146
119
|
debug "item is a set name"
|
|
147
|
-
|
|
120
|
+
lBlocks = for item in @hSets[desc]
|
|
121
|
+
if isArray(item)
|
|
122
|
+
@getBlock item[0]
|
|
123
|
+
else if isString(item)
|
|
124
|
+
@getBlock item
|
|
125
|
+
else
|
|
126
|
+
croak "Item in set #{desc} is not a string or array"
|
|
127
|
+
block = toBlock(lBlocks)
|
|
128
|
+
replacer = @hReplacers[desc]
|
|
129
|
+
debug "replacer for is #{OL(replacer)}"
|
|
130
|
+
if def(replacer)
|
|
131
|
+
block = replacer(block)
|
|
132
|
+
else if isString(desc)
|
|
133
|
+
debug "item is a literal string"
|
|
134
|
+
# --- a literal string
|
|
135
|
+
block = desc
|
|
136
|
+
else if isArray(desc)
|
|
137
|
+
debug "item is an array"
|
|
138
|
+
lBlocks = for item in desc
|
|
139
|
+
@getBlock(item)
|
|
140
|
+
block = toBlock(lBlocks)
|
|
148
141
|
else
|
|
149
|
-
croak "Bad
|
|
142
|
+
croak "Bad arg: #{OL(desc)}"
|
|
143
|
+
|
|
150
144
|
debug "return from SectionMap.getBlock()", block
|
|
151
145
|
return block
|
|
152
146
|
|
|
147
|
+
# ..........................................................
|
|
148
|
+
# --- does NOT call any replacers, and skips literal strings
|
|
149
|
+
# so only useful for isEmpty() and nonEmpty()
|
|
150
|
+
|
|
151
|
+
allSections: (desc=undef) ->
|
|
152
|
+
|
|
153
|
+
debug "enter allSections()", desc
|
|
154
|
+
if notdef(desc)
|
|
155
|
+
desc = @lFullTree
|
|
156
|
+
|
|
157
|
+
if isSectionName(desc)
|
|
158
|
+
debug "is section name"
|
|
159
|
+
yield @section(desc)
|
|
160
|
+
else if isSetName(desc)
|
|
161
|
+
debug "is set name"
|
|
162
|
+
for name in @hSets[desc]
|
|
163
|
+
yield from @allSections(name)
|
|
164
|
+
else if isArray(desc)
|
|
165
|
+
debug "is array"
|
|
166
|
+
for item in desc
|
|
167
|
+
yield from @allSections(item)
|
|
168
|
+
debug "return from allSections()"
|
|
169
|
+
return
|
|
170
|
+
|
|
153
171
|
# ..........................................................
|
|
154
172
|
|
|
155
|
-
isEmpty: () ->
|
|
173
|
+
isEmpty: (desc=undef) ->
|
|
156
174
|
|
|
157
|
-
for
|
|
175
|
+
for sect from @allSections(desc)
|
|
158
176
|
if sect.nonEmpty()
|
|
159
177
|
return false
|
|
160
178
|
return true
|
|
161
179
|
|
|
162
180
|
# ..........................................................
|
|
163
181
|
|
|
164
|
-
nonEmpty: () ->
|
|
182
|
+
nonEmpty: (desc=undef) ->
|
|
165
183
|
|
|
166
|
-
for
|
|
184
|
+
for sect from @allSections(desc)
|
|
167
185
|
if sect.nonEmpty()
|
|
168
186
|
return true
|
|
169
187
|
return false
|
|
@@ -173,7 +191,7 @@ export class SectionMap
|
|
|
173
191
|
section: (name) ->
|
|
174
192
|
|
|
175
193
|
sect = @hSections[name]
|
|
176
|
-
assert
|
|
194
|
+
assert def(sect), "No section named #{OL(name)}"
|
|
177
195
|
return sect
|
|
178
196
|
|
|
179
197
|
# ..........................................................
|
|
@@ -182,8 +200,8 @@ export class SectionMap
|
|
|
182
200
|
|
|
183
201
|
assert isSetName(name), "bad set name #{OL(name)}"
|
|
184
202
|
lSubTree = @hSets[name]
|
|
185
|
-
assert
|
|
186
|
-
return @section(lSubTree[
|
|
203
|
+
assert def(lSubTree), "no such set #{OL(name)}"
|
|
204
|
+
return @section(lSubTree[0])
|
|
187
205
|
|
|
188
206
|
# ..........................................................
|
|
189
207
|
|
|
@@ -191,5 +209,37 @@ export class SectionMap
|
|
|
191
209
|
|
|
192
210
|
assert isSetName(name), "bad set name #{OL(name)}"
|
|
193
211
|
lSubTree = @hSets[name]
|
|
194
|
-
assert
|
|
212
|
+
assert def(lSubTree), "no such set #{OL(name)}"
|
|
195
213
|
return @section(lSubTree[lSubTree.length - 1])
|
|
214
|
+
|
|
215
|
+
# ..........................................................
|
|
216
|
+
|
|
217
|
+
checkTree: (tree) ->
|
|
218
|
+
|
|
219
|
+
debug "enter checkTree()"
|
|
220
|
+
if isString(tree)
|
|
221
|
+
debug "tree is a string"
|
|
222
|
+
assert isTAML(tree), "not TAML"
|
|
223
|
+
@lFullTree = fromTAML(tree)
|
|
224
|
+
else
|
|
225
|
+
@lFullTree = tree
|
|
226
|
+
|
|
227
|
+
assert isArray(@lFullTree), "not an array"
|
|
228
|
+
assert nonEmpty(@lFullTree), "tree is empty"
|
|
229
|
+
if isSetName(@lFullTree[0])
|
|
230
|
+
LOGTAML 'lFullTree', @lFullTree
|
|
231
|
+
croak "tree cannot begin with a set name"
|
|
232
|
+
debug "return from checkTree()"
|
|
233
|
+
return
|
|
234
|
+
|
|
235
|
+
# ..........................................................
|
|
236
|
+
|
|
237
|
+
checkReplacers: (h) ->
|
|
238
|
+
|
|
239
|
+
assert isHash(h), "replacers is not a hash"
|
|
240
|
+
for key,func of h
|
|
241
|
+
assert isSetName(key) || isSectionName(key), "bad replacer key"
|
|
242
|
+
assert isFunction(func),
|
|
243
|
+
"replacer for #{OL(key)} is not a function"
|
|
244
|
+
return
|
|
245
|
+
|
package/src/SectionMap.js
CHANGED
|
@@ -4,22 +4,20 @@ var isSectionName, isSetName;
|
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
assert,
|
|
7
|
-
croak
|
|
7
|
+
croak,
|
|
8
|
+
LOG,
|
|
9
|
+
LOGVALUE,
|
|
10
|
+
LOGTAML,
|
|
11
|
+
debug,
|
|
12
|
+
isTAML,
|
|
13
|
+
fromTAML
|
|
8
14
|
} from '@jdeighan/exceptions';
|
|
9
15
|
|
|
10
|
-
import {
|
|
11
|
-
LOG
|
|
12
|
-
} from '@jdeighan/exceptions/log';
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
debug
|
|
16
|
-
} from '@jdeighan/exceptions/debug';
|
|
17
|
-
|
|
18
16
|
import {
|
|
19
17
|
pass,
|
|
20
18
|
undef,
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
def,
|
|
20
|
+
notdef,
|
|
23
21
|
OL,
|
|
24
22
|
isEmpty,
|
|
25
23
|
nonEmpty,
|
|
@@ -28,18 +26,16 @@ import {
|
|
|
28
26
|
isArray,
|
|
29
27
|
isUniqueTree,
|
|
30
28
|
isNonEmptyString,
|
|
31
|
-
isNonEmptyArray
|
|
29
|
+
isNonEmptyArray,
|
|
30
|
+
isFunction,
|
|
31
|
+
jsType,
|
|
32
|
+
isArrayOfStrings
|
|
32
33
|
} from '@jdeighan/coffee-utils';
|
|
33
34
|
|
|
34
35
|
import {
|
|
35
36
|
toBlock
|
|
36
37
|
} from '@jdeighan/coffee-utils/block';
|
|
37
38
|
|
|
38
|
-
import {
|
|
39
|
-
isTAML,
|
|
40
|
-
fromTAML
|
|
41
|
-
} from '@jdeighan/coffee-utils/taml';
|
|
42
|
-
|
|
43
39
|
import {
|
|
44
40
|
Section
|
|
45
41
|
} from '@jdeighan/coffee-utils/section';
|
|
@@ -56,142 +52,170 @@ isSetName = function(name) {
|
|
|
56
52
|
|
|
57
53
|
// ---------------------------------------------------------------------------
|
|
58
54
|
export var SectionMap = class SectionMap {
|
|
59
|
-
constructor(
|
|
60
|
-
this.
|
|
61
|
-
// ---
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
//
|
|
68
|
-
this.
|
|
69
|
-
|
|
70
|
-
this.
|
|
71
|
-
this.
|
|
72
|
-
|
|
55
|
+
constructor(tree, hReplacers = {}) {
|
|
56
|
+
this.hReplacers = hReplacers;
|
|
57
|
+
// --- tree is a tree of section/set names
|
|
58
|
+
// or a TAML string that converts to one
|
|
59
|
+
// --- hReplacers are callbacks that are called
|
|
60
|
+
// when a set or section is processed
|
|
61
|
+
// should be <name> -> <function>
|
|
62
|
+
// <name> can be a section name or a set name
|
|
63
|
+
// <function> should be <block> -> <block>
|
|
64
|
+
debug("enter SectionMap()", tree, this.hReplacers);
|
|
65
|
+
this.checkTree(tree);
|
|
66
|
+
this.checkReplacers(this.hReplacers);
|
|
67
|
+
this.hSections = {}; // --- {section name: Section Object}
|
|
68
|
+
this.hSets = {
|
|
69
|
+
ALL: this.lFullTree // --- {set name: array of parts}
|
|
70
|
+
};
|
|
71
|
+
this.init(this.lFullTree);
|
|
72
|
+
debug('hSections', this.hSections);
|
|
73
|
+
debug('hSets', this.hSets);
|
|
74
|
+
debug("return from SectionMap()");
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
// ..........................................................
|
|
76
|
-
|
|
77
|
-
var firstItem, i, item,
|
|
78
|
-
debug("enter
|
|
78
|
+
init(lTree) {
|
|
79
|
+
var firstItem, i, item, len;
|
|
80
|
+
debug("enter init()", lTree);
|
|
79
81
|
assert(isArray(lTree), "not an array");
|
|
80
82
|
assert(nonEmpty(lTree), "empty array");
|
|
81
83
|
firstItem = lTree[0];
|
|
82
84
|
if (isSetName(firstItem)) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
for (j = 0, len1 = lTree.length; j < len1; j++) {
|
|
98
|
-
item = lTree[j];
|
|
99
|
-
if (isArray(item)) {
|
|
100
|
-
this.build(item);
|
|
101
|
-
} else if (isSectionName(item)) {
|
|
102
|
-
this.hSections[item] = new Section(item);
|
|
103
|
-
} else {
|
|
104
|
-
croak(`Bad section tree: ${OL(this.lSectionTree)}`);
|
|
105
|
-
}
|
|
85
|
+
debug(`found set name ${OL(firstItem)}`);
|
|
86
|
+
lTree = lTree.slice(1);
|
|
87
|
+
this.mkSet(firstItem, lTree);
|
|
88
|
+
}
|
|
89
|
+
for (i = 0, len = lTree.length; i < len; i++) {
|
|
90
|
+
item = lTree[i];
|
|
91
|
+
if (isArray(item)) {
|
|
92
|
+
debug("init subtree");
|
|
93
|
+
this.init(item);
|
|
94
|
+
} else if (isSectionName(item)) {
|
|
95
|
+
debug(`mkSection ${OL(item)}`);
|
|
96
|
+
this.mkSection(item);
|
|
97
|
+
} else {
|
|
98
|
+
assert(isString(item), `Bad item in tree: ${OL(item)}`);
|
|
106
99
|
}
|
|
107
100
|
}
|
|
108
|
-
debug("return from
|
|
101
|
+
debug("return from init()");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ..........................................................
|
|
105
|
+
mkSet(name, lTree) {
|
|
106
|
+
assert(isArray(lTree), "tree is not an array");
|
|
107
|
+
assert(nonEmpty(lTree), "set without sections");
|
|
108
|
+
assert(notdef(this.hSets[name]), `set ${OL(name)} already exists`);
|
|
109
|
+
this.hSets[name] = lTree;
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
// ..........................................................
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
//
|
|
124
|
-
//
|
|
125
|
-
//
|
|
126
|
-
if (
|
|
127
|
-
debug(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
debug("desc is entire tree");
|
|
133
|
-
desc = this.lSectionTree;
|
|
113
|
+
mkSection(name) {
|
|
114
|
+
assert(notdef(this.hSections[name]), "duplicate section name");
|
|
115
|
+
this.hSections[name] = new Section(name, this.hReplacers[name]);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ..........................................................
|
|
119
|
+
getBlock(desc = 'ALL') {
|
|
120
|
+
var block, item, lBlocks, replacer;
|
|
121
|
+
// ..........................................................
|
|
122
|
+
// --- desc can be:
|
|
123
|
+
// a section name
|
|
124
|
+
// a set name
|
|
125
|
+
// an array of section or set names or literal strings
|
|
126
|
+
// i.e. it should NOT contain sub-arrays
|
|
127
|
+
if (isString(desc)) {
|
|
128
|
+
debug(`enter SectionMap.getBlock(${OL(desc)})`);
|
|
129
|
+
} else if (isArrayOfStrings(desc)) {
|
|
130
|
+
debug("enter SectionMap.getBlock()", desc);
|
|
131
|
+
} else {
|
|
132
|
+
croak(`Bad desc: ${OL(desc)}`);
|
|
134
133
|
}
|
|
135
|
-
if (
|
|
136
|
-
debug("item is
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (
|
|
148
|
-
|
|
149
|
-
|
|
134
|
+
if (isSectionName(desc)) {
|
|
135
|
+
debug("item is a section name");
|
|
136
|
+
// --- a section's getBlock() applies any replacer
|
|
137
|
+
block = this.section(desc).getBlock();
|
|
138
|
+
} else if (isSetName(desc)) {
|
|
139
|
+
debug("item is a set name");
|
|
140
|
+
lBlocks = (function() {
|
|
141
|
+
var i, len, ref, results;
|
|
142
|
+
ref = this.hSets[desc];
|
|
143
|
+
results = [];
|
|
144
|
+
for (i = 0, len = ref.length; i < len; i++) {
|
|
145
|
+
item = ref[i];
|
|
146
|
+
if (isArray(item)) {
|
|
147
|
+
results.push(this.getBlock(item[0]));
|
|
148
|
+
} else if (isString(item)) {
|
|
149
|
+
results.push(this.getBlock(item));
|
|
150
150
|
} else {
|
|
151
|
-
|
|
151
|
+
results.push(croak(`Item in set ${desc} is not a string or array`));
|
|
152
152
|
}
|
|
153
|
-
} else if (isString(item) && nonEmpty(item)) {
|
|
154
|
-
debug("add string", item);
|
|
155
|
-
lBlocks.push(item);
|
|
156
|
-
} else {
|
|
157
|
-
croak(`Bad item: ${OL(item)}`);
|
|
158
153
|
}
|
|
159
|
-
|
|
154
|
+
return results;
|
|
155
|
+
}).call(this);
|
|
160
156
|
block = toBlock(lBlocks);
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
debug(`REPLACE ${setName} with`, block);
|
|
166
|
-
} else {
|
|
167
|
-
debug(`NO REPLACER for ${setName}`);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
} else if (isSectionName(desc)) {
|
|
171
|
-
debug("item is a section name");
|
|
172
|
-
block = this.section(desc).getBlock();
|
|
173
|
-
if (defined(proc = hReplacers[desc])) {
|
|
174
|
-
debug(`REPLACE ${desc}`);
|
|
175
|
-
block = proc(block);
|
|
176
|
-
} else {
|
|
177
|
-
debug(`NO REPLACER for ${desc}`);
|
|
157
|
+
replacer = this.hReplacers[desc];
|
|
158
|
+
debug(`replacer for is ${OL(replacer)}`);
|
|
159
|
+
if (def(replacer)) {
|
|
160
|
+
block = replacer(block);
|
|
178
161
|
}
|
|
179
|
-
} else if (
|
|
180
|
-
debug("item is a
|
|
181
|
-
|
|
162
|
+
} else if (isString(desc)) {
|
|
163
|
+
debug("item is a literal string");
|
|
164
|
+
// --- a literal string
|
|
165
|
+
block = desc;
|
|
166
|
+
} else if (isArray(desc)) {
|
|
167
|
+
debug("item is an array");
|
|
168
|
+
lBlocks = (function() {
|
|
169
|
+
var i, len, results;
|
|
170
|
+
results = [];
|
|
171
|
+
for (i = 0, len = desc.length; i < len; i++) {
|
|
172
|
+
item = desc[i];
|
|
173
|
+
results.push(this.getBlock(item));
|
|
174
|
+
}
|
|
175
|
+
return results;
|
|
176
|
+
}).call(this);
|
|
177
|
+
block = toBlock(lBlocks);
|
|
182
178
|
} else {
|
|
183
|
-
croak(`Bad
|
|
179
|
+
croak(`Bad arg: ${OL(desc)}`);
|
|
184
180
|
}
|
|
185
181
|
debug("return from SectionMap.getBlock()", block);
|
|
186
182
|
return block;
|
|
187
183
|
}
|
|
188
184
|
|
|
189
185
|
// ..........................................................
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
186
|
+
// --- does NOT call any replacers, and skips literal strings
|
|
187
|
+
// so only useful for isEmpty() and nonEmpty()
|
|
188
|
+
* allSections(desc = undef) {
|
|
189
|
+
var i, item, j, len, len1, name, ref;
|
|
190
|
+
debug("enter allSections()", desc);
|
|
191
|
+
if (notdef(desc)) {
|
|
192
|
+
desc = this.lFullTree;
|
|
193
|
+
}
|
|
194
|
+
if (isSectionName(desc)) {
|
|
195
|
+
debug("is section name");
|
|
196
|
+
yield this.section(desc);
|
|
197
|
+
} else if (isSetName(desc)) {
|
|
198
|
+
debug("is set name");
|
|
199
|
+
ref = this.hSets[desc];
|
|
200
|
+
for (i = 0, len = ref.length; i < len; i++) {
|
|
201
|
+
name = ref[i];
|
|
202
|
+
yield* this.allSections(name);
|
|
203
|
+
}
|
|
204
|
+
} else if (isArray(desc)) {
|
|
205
|
+
debug("is array");
|
|
206
|
+
for (j = 0, len1 = desc.length; j < len1; j++) {
|
|
207
|
+
item = desc[j];
|
|
208
|
+
yield* this.allSections(item);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
debug("return from allSections()");
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// ..........................................................
|
|
215
|
+
isEmpty(desc = undef) {
|
|
216
|
+
var ref, sect;
|
|
217
|
+
ref = this.allSections(desc);
|
|
218
|
+
for (sect of ref) {
|
|
195
219
|
if (sect.nonEmpty()) {
|
|
196
220
|
return false;
|
|
197
221
|
}
|
|
@@ -200,11 +224,10 @@ export var SectionMap = class SectionMap {
|
|
|
200
224
|
}
|
|
201
225
|
|
|
202
226
|
// ..........................................................
|
|
203
|
-
nonEmpty() {
|
|
204
|
-
var
|
|
205
|
-
ref = this.
|
|
206
|
-
for (
|
|
207
|
-
sect = ref[name];
|
|
227
|
+
nonEmpty(desc = undef) {
|
|
228
|
+
var ref, sect;
|
|
229
|
+
ref = this.allSections(desc);
|
|
230
|
+
for (sect of ref) {
|
|
208
231
|
if (sect.nonEmpty()) {
|
|
209
232
|
return true;
|
|
210
233
|
}
|
|
@@ -216,7 +239,7 @@ export var SectionMap = class SectionMap {
|
|
|
216
239
|
section(name) {
|
|
217
240
|
var sect;
|
|
218
241
|
sect = this.hSections[name];
|
|
219
|
-
assert(
|
|
242
|
+
assert(def(sect), `No section named ${OL(name)}`);
|
|
220
243
|
return sect;
|
|
221
244
|
}
|
|
222
245
|
|
|
@@ -225,8 +248,8 @@ export var SectionMap = class SectionMap {
|
|
|
225
248
|
var lSubTree;
|
|
226
249
|
assert(isSetName(name), `bad set name ${OL(name)}`);
|
|
227
250
|
lSubTree = this.hSets[name];
|
|
228
|
-
assert(
|
|
229
|
-
return this.section(lSubTree[
|
|
251
|
+
assert(def(lSubTree), `no such set ${OL(name)}`);
|
|
252
|
+
return this.section(lSubTree[0]);
|
|
230
253
|
}
|
|
231
254
|
|
|
232
255
|
// ..........................................................
|
|
@@ -234,8 +257,38 @@ export var SectionMap = class SectionMap {
|
|
|
234
257
|
var lSubTree;
|
|
235
258
|
assert(isSetName(name), `bad set name ${OL(name)}`);
|
|
236
259
|
lSubTree = this.hSets[name];
|
|
237
|
-
assert(
|
|
260
|
+
assert(def(lSubTree), `no such set ${OL(name)}`);
|
|
238
261
|
return this.section(lSubTree[lSubTree.length - 1]);
|
|
239
262
|
}
|
|
240
263
|
|
|
264
|
+
// ..........................................................
|
|
265
|
+
checkTree(tree) {
|
|
266
|
+
debug("enter checkTree()");
|
|
267
|
+
if (isString(tree)) {
|
|
268
|
+
debug("tree is a string");
|
|
269
|
+
assert(isTAML(tree), "not TAML");
|
|
270
|
+
this.lFullTree = fromTAML(tree);
|
|
271
|
+
} else {
|
|
272
|
+
this.lFullTree = tree;
|
|
273
|
+
}
|
|
274
|
+
assert(isArray(this.lFullTree), "not an array");
|
|
275
|
+
assert(nonEmpty(this.lFullTree), "tree is empty");
|
|
276
|
+
if (isSetName(this.lFullTree[0])) {
|
|
277
|
+
LOGTAML('lFullTree', this.lFullTree);
|
|
278
|
+
croak("tree cannot begin with a set name");
|
|
279
|
+
}
|
|
280
|
+
debug("return from checkTree()");
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// ..........................................................
|
|
284
|
+
checkReplacers(h) {
|
|
285
|
+
var func, key;
|
|
286
|
+
assert(isHash(h), "replacers is not a hash");
|
|
287
|
+
for (key in h) {
|
|
288
|
+
func = h[key];
|
|
289
|
+
assert(isSetName(key) || isSectionName(key), "bad replacer key");
|
|
290
|
+
assert(isFunction(func), `replacer for ${OL(key)} is not a function`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
241
294
|
};
|
package/src/block.coffee
CHANGED
|
@@ -63,7 +63,8 @@ export toBlock = (lLines) ->
|
|
|
63
63
|
|
|
64
64
|
if notdefined(lLines)
|
|
65
65
|
return undef
|
|
66
|
-
assert isArrayOfStrings(lLines),
|
|
66
|
+
assert isArrayOfStrings(lLines),
|
|
67
|
+
"lLines is not an array of strings: #{OL(lLines)}"
|
|
67
68
|
lNewLines = []
|
|
68
69
|
for line in lLines
|
|
69
70
|
if defined(line)
|
package/src/block.js
CHANGED
|
@@ -90,7 +90,7 @@ export var toBlock = function(lLines) {
|
|
|
90
90
|
if (notdefined(lLines)) {
|
|
91
91
|
return undef;
|
|
92
92
|
}
|
|
93
|
-
assert(isArrayOfStrings(lLines), `lLines is not an array: ${OL(lLines)}`);
|
|
93
|
+
assert(isArrayOfStrings(lLines), `lLines is not an array of strings: ${OL(lLines)}`);
|
|
94
94
|
lNewLines = [];
|
|
95
95
|
for (i = 0, len = lLines.length; i < len; i++) {
|
|
96
96
|
line = lLines[i];
|
package/src/fs.coffee
CHANGED
|
@@ -5,7 +5,7 @@ import urllib from 'url'
|
|
|
5
5
|
import fs from 'fs'
|
|
6
6
|
import NReadLines from 'n-readlines'
|
|
7
7
|
|
|
8
|
-
import {assert, croak, LOG, fromTAML} from '@jdeighan/exceptions'
|
|
8
|
+
import {assert, croak, debug, LOG, fromTAML} from '@jdeighan/exceptions'
|
|
9
9
|
import {
|
|
10
10
|
undef, pass, defined, rtrim, isEmpty, nonEmpty, getOptions,
|
|
11
11
|
isString, isArray, isHash, isRegExp, isFunction, OL,
|
|
@@ -377,6 +377,7 @@ export parseSource = (source) ->
|
|
|
377
377
|
# }
|
|
378
378
|
# --- NOTE: source may be a file URL, e.g. import.meta.url
|
|
379
379
|
|
|
380
|
+
debug "enter parseSource(#{OL(source)})"
|
|
380
381
|
assert isString(source),\
|
|
381
382
|
"parseSource(): source not a string: #{OL(source)}"
|
|
382
383
|
if source == 'unit test'
|
|
@@ -413,6 +414,7 @@ export parseSource = (source) ->
|
|
|
413
414
|
([A-Za-z_]+)
|
|
414
415
|
$///)
|
|
415
416
|
hSourceInfo.purpose = lMatches[1]
|
|
417
|
+
debug "return from parseSource()", hSourceInfo
|
|
416
418
|
return hSourceInfo
|
|
417
419
|
|
|
418
420
|
# ---------------------------------------------------------------------------
|
package/src/fs.js
CHANGED
|
@@ -13,6 +13,7 @@ import NReadLines from 'n-readlines';
|
|
|
13
13
|
import {
|
|
14
14
|
assert,
|
|
15
15
|
croak,
|
|
16
|
+
debug,
|
|
16
17
|
LOG,
|
|
17
18
|
fromTAML
|
|
18
19
|
} from '@jdeighan/exceptions';
|
|
@@ -446,6 +447,7 @@ export var parseSource = function(source) {
|
|
|
446
447
|
// purpose
|
|
447
448
|
// }
|
|
448
449
|
// --- NOTE: source may be a file URL, e.g. import.meta.url
|
|
450
|
+
debug(`enter parseSource(${OL(source)})`);
|
|
449
451
|
assert(isString(source), `parseSource(): source not a string: ${OL(source)}`);
|
|
450
452
|
if (source === 'unit test') {
|
|
451
453
|
croak("A source of 'unit test' is deprecated");
|
|
@@ -481,6 +483,7 @@ export var parseSource = function(source) {
|
|
|
481
483
|
hSourceInfo.purpose = lMatches[1];
|
|
482
484
|
}
|
|
483
485
|
}
|
|
486
|
+
debug("return from parseSource()", hSourceInfo);
|
|
484
487
|
return hSourceInfo;
|
|
485
488
|
};
|
|
486
489
|
|
package/src/utils.coffee
CHANGED
|
@@ -11,8 +11,11 @@ import {
|
|
|
11
11
|
isEmpty, nonEmpty, chomp, rtrim, setCharsAt, words, getOptions,
|
|
12
12
|
} from '@jdeighan/exceptions/utils'
|
|
13
13
|
|
|
14
|
+
def = defined
|
|
15
|
+
notdef = notdefined
|
|
16
|
+
|
|
14
17
|
export {
|
|
15
|
-
undef, pass, defined, notdefined, LOG, sep_dash, sep_eq,
|
|
18
|
+
undef, pass, def, defined, notdef, notdefined, LOG, sep_dash, sep_eq,
|
|
16
19
|
deepCopy, escapeStr, unescapeStr, hasChar, quoted, OL,
|
|
17
20
|
isString, isNumber, isInteger, isHash, isArray, isBoolean,
|
|
18
21
|
isConstructor, isFunction, isRegExp, isObject, getClassName,
|
|
@@ -137,22 +140,24 @@ export pushCond = (lItems, item, doPush=notInArray) ->
|
|
|
137
140
|
# ---------------------------------------------------------------------------
|
|
138
141
|
|
|
139
142
|
export isArrayOfHashes = (lItems) ->
|
|
143
|
+
# --- undefined items are allowed
|
|
140
144
|
|
|
141
145
|
if ! isArray(lItems)
|
|
142
146
|
return false
|
|
143
147
|
for item in lItems
|
|
144
|
-
if ! isHash(item)
|
|
148
|
+
if defined(item) && ! isHash(item)
|
|
145
149
|
return false
|
|
146
150
|
return true
|
|
147
151
|
|
|
148
152
|
# ---------------------------------------------------------------------------
|
|
149
153
|
|
|
150
154
|
export isArrayOfStrings = (lItems) ->
|
|
155
|
+
# --- undefined items are allowed
|
|
151
156
|
|
|
152
157
|
if ! isArray(lItems)
|
|
153
158
|
return false
|
|
154
159
|
for item in lItems
|
|
155
|
-
if ! isString(item)
|
|
160
|
+
if defined(item) && ! isString(item)
|
|
156
161
|
return false
|
|
157
162
|
return true
|
|
158
163
|
|
package/src/utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Generated by CoffeeScript 2.7.0
|
|
2
|
-
// utils.coffee
|
|
3
|
-
var
|
|
2
|
+
// utils.coffee
|
|
3
|
+
var def, notdef,
|
|
4
|
+
hasProp = {}.hasOwnProperty;
|
|
4
5
|
|
|
5
6
|
import {
|
|
6
7
|
assert,
|
|
@@ -45,10 +46,16 @@ import {
|
|
|
45
46
|
getOptions
|
|
46
47
|
} from '@jdeighan/exceptions/utils';
|
|
47
48
|
|
|
49
|
+
def = defined;
|
|
50
|
+
|
|
51
|
+
notdef = notdefined;
|
|
52
|
+
|
|
48
53
|
export {
|
|
49
54
|
undef,
|
|
50
55
|
pass,
|
|
56
|
+
def,
|
|
51
57
|
defined,
|
|
58
|
+
notdef,
|
|
52
59
|
notdefined,
|
|
53
60
|
LOG,
|
|
54
61
|
sep_dash,
|
|
@@ -202,7 +209,7 @@ export var isArrayOfHashes = function(lItems) {
|
|
|
202
209
|
}
|
|
203
210
|
for (i = 0, len = lItems.length; i < len; i++) {
|
|
204
211
|
item = lItems[i];
|
|
205
|
-
if (!isHash(item)) {
|
|
212
|
+
if (defined(item) && !isHash(item)) {
|
|
206
213
|
return false;
|
|
207
214
|
}
|
|
208
215
|
}
|
|
@@ -217,7 +224,7 @@ export var isArrayOfStrings = function(lItems) {
|
|
|
217
224
|
}
|
|
218
225
|
for (i = 0, len = lItems.length; i < len; i++) {
|
|
219
226
|
item = lItems[i];
|
|
220
|
-
if (!isString(item)) {
|
|
227
|
+
if (defined(item) && !isString(item)) {
|
|
221
228
|
return false;
|
|
222
229
|
}
|
|
223
230
|
}
|
package/src/placeholders.coffee
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# placeholders.coffee
|
|
2
|
-
|
|
3
|
-
import {assert, croak} from '@jdeighan/exceptions'
|
|
4
|
-
import {undef, defined} from '@jdeighan/coffee-utils'
|
|
5
|
-
|
|
6
|
-
hDefOptions = {
|
|
7
|
-
pre: '__'
|
|
8
|
-
post: '__'
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
# ---------------------------------------------------------------------------
|
|
12
|
-
|
|
13
|
-
export phStr = (name, hOptions=hDefOptions) ->
|
|
14
|
-
|
|
15
|
-
{pre, post} = hOptions
|
|
16
|
-
return "#{pre}#{name}#{post}"
|
|
17
|
-
|
|
18
|
-
# ---------------------------------------------------------------------------
|
|
19
|
-
|
|
20
|
-
export phReplace = (str, hValues, hOptions=hDefOptions) ->
|
|
21
|
-
|
|
22
|
-
{pre, post} = hOptions
|
|
23
|
-
return str.replace(
|
|
24
|
-
/// #{pre} ([A-Za-z_][A-Za-z0-9_]*) #{post} ///g,
|
|
25
|
-
(_, name) -> hValues[name]
|
|
26
|
-
)
|
package/src/placeholders.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// Generated by CoffeeScript 2.7.0
|
|
2
|
-
// placeholders.coffee
|
|
3
|
-
var hDefOptions;
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
assert,
|
|
7
|
-
croak
|
|
8
|
-
} from '@jdeighan/exceptions';
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
undef,
|
|
12
|
-
defined
|
|
13
|
-
} from '@jdeighan/coffee-utils';
|
|
14
|
-
|
|
15
|
-
hDefOptions = {
|
|
16
|
-
pre: '__',
|
|
17
|
-
post: '__'
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
export var phStr = function(name, hOptions = hDefOptions) {
|
|
22
|
-
var post, pre;
|
|
23
|
-
({pre, post} = hOptions);
|
|
24
|
-
return `${pre}${name}${post}`;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
// ---------------------------------------------------------------------------
|
|
28
|
-
export var phReplace = function(str, hValues, hOptions = hDefOptions) {
|
|
29
|
-
var post, pre;
|
|
30
|
-
({pre, post} = hOptions);
|
|
31
|
-
return str.replace(RegExp(`${pre}([A-Za-z_][A-Za-z0-9_]*)${post}`, "g"), function(_, name) {
|
|
32
|
-
return hValues[name];
|
|
33
|
-
});
|
|
34
|
-
};
|