@jdeighan/coffee-utils 16.0.24 → 17.0.0
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 -9
- package/src/lib/KeyedSet.js +2 -0
- package/src/lib/KeyedSet.js.map +13 -0
- package/src/lib/Section.js +2 -0
- package/src/lib/Section.js.map +13 -0
- package/src/lib/SectionMap.js +2 -0
- package/src/lib/SectionMap.js.map +13 -0
- package/src/lib/block.js +2 -0
- package/src/lib/block.js.map +13 -0
- package/src/lib/cssUtils.js +2 -0
- package/src/lib/cssUtils.js.map +13 -0
- package/src/lib/fs.coffee +76 -133
- package/src/lib/fs.js +95 -155
- package/src/lib/fs.js.map +13 -0
- package/src/lib/fsa.js +2 -0
- package/src/lib/fsa.js.map +13 -0
- package/src/lib/html.coffee +2 -2
- package/src/lib/html.js +8 -6
- package/src/lib/html.js.map +13 -0
- package/src/lib/server.js +2 -0
- package/src/lib/server.js.map +13 -0
- package/src/lib/indent.coffee +0 -199
- package/src/lib/indent.js +0 -216
package/src/lib/indent.coffee
DELETED
@@ -1,199 +0,0 @@
|
|
1
|
-
# indent.coffee
|
2
|
-
|
3
|
-
import {assert, croak} from '@jdeighan/base-utils/exceptions'
|
4
|
-
import {
|
5
|
-
undef, defined, notdefined, toArray, toBlock,
|
6
|
-
OL, isInteger, isString, isArray, isEmpty, rtrim,
|
7
|
-
} from '@jdeighan/base-utils'
|
8
|
-
|
9
|
-
# ---------------------------------------------------------------------------
|
10
|
-
|
11
|
-
export getOneIndent = (str) =>
|
12
|
-
|
13
|
-
if (lMatches = str.match(/^\t+(?:\S|$)/))
|
14
|
-
return "\t"
|
15
|
-
else if (lMatches = str.match(/^(\x20+)(?:\S|$)/)) # space char
|
16
|
-
return lMatches[1]
|
17
|
-
assert notdefined(str.match(/^\s/)), "Mixed indentation types"
|
18
|
-
return undef
|
19
|
-
|
20
|
-
# ---------------------------------------------------------------------------
|
21
|
-
|
22
|
-
export splitPrefix = (line) =>
|
23
|
-
|
24
|
-
assert isString(line), "non-string #{OL(line)}"
|
25
|
-
line = rtrim(line)
|
26
|
-
lMatches = line.match(/^(\s*)(.*)$/)
|
27
|
-
return [lMatches[1], lMatches[2]]
|
28
|
-
|
29
|
-
# ---------------------------------------------------------------------------
|
30
|
-
# splitLine - separate a line into [level, line]
|
31
|
-
|
32
|
-
export splitLine = (line, oneIndent=undef) =>
|
33
|
-
|
34
|
-
[prefix, str] = splitPrefix(line)
|
35
|
-
return [indentLevel(prefix, oneIndent), str]
|
36
|
-
|
37
|
-
# ---------------------------------------------------------------------------
|
38
|
-
# indentLevel - determine indent level of a string
|
39
|
-
# it's OK if the string is ONLY indentation
|
40
|
-
|
41
|
-
export indentLevel = (line, oneIndent=undef) =>
|
42
|
-
|
43
|
-
assert isString(line), "not a string"
|
44
|
-
|
45
|
-
# --- This will always match, and it's greedy
|
46
|
-
if lMatches = line.match(/^\s*/)
|
47
|
-
prefix = lMatches[0]
|
48
|
-
prefixLen = prefix.length
|
49
|
-
|
50
|
-
if (prefixLen == 0)
|
51
|
-
return 0
|
52
|
-
|
53
|
-
# --- Match \t* followed by \x20* (error if no match)
|
54
|
-
if lMatches = prefix.match(/(\t*)(\x20*)/)
|
55
|
-
nTabs = lMatches[1].length
|
56
|
-
nSpaces = lMatches[2].length
|
57
|
-
else
|
58
|
-
croak "Invalid mix of TABs and spaces"
|
59
|
-
|
60
|
-
# --- oneIndent must be one of:
|
61
|
-
# undef
|
62
|
-
# a single TAB character
|
63
|
-
# some number of space characters
|
64
|
-
|
65
|
-
switch oneIndent
|
66
|
-
when undef
|
67
|
-
if (nTabs > 0)
|
68
|
-
level = nTabs # there may also be spaces, but we ignore them
|
69
|
-
oneIndent = "\t" # may be used at end
|
70
|
-
else
|
71
|
-
assert (nSpaces > 0), "There must be TABS or spaces"
|
72
|
-
level = 1
|
73
|
-
oneIndent = ' '.repeat(nSpaces) # may be used at end
|
74
|
-
when "\t"
|
75
|
-
assert (nTabs > 0), "Expecting TAB indentation, found spaces"
|
76
|
-
# --- NOTE: there may be spaces, but they're not indentation
|
77
|
-
level = nTabs
|
78
|
-
else
|
79
|
-
# --- oneIndent must be all space chars
|
80
|
-
assert (nTabs == 0),
|
81
|
-
"Indentation has TABs but oneIndent = #{OL(oneIndent)}"
|
82
|
-
assert (nSpaces % oneIndent.length == 0),
|
83
|
-
"prefix #{OL(prefix)} not a mult of #{OL(oneIndent)}"
|
84
|
-
level = nSpaces / oneIndent.length
|
85
|
-
|
86
|
-
# --- If a block, i.e. multi-line string, then all lines must be
|
87
|
-
# at least at this level
|
88
|
-
if (line.indexOf("\n") >= 0)
|
89
|
-
for str in toArray(line)
|
90
|
-
assert (indentLevel(str, oneIndent) >= level),
|
91
|
-
"indentLevel of #{OL(line)} can't be found"
|
92
|
-
return level
|
93
|
-
|
94
|
-
# ---------------------------------------------------------------------------
|
95
|
-
# indentation - return appropriate indentation string for given level
|
96
|
-
# export only to allow unit testing
|
97
|
-
|
98
|
-
export indentation = (level, oneIndent="\t") =>
|
99
|
-
|
100
|
-
assert (level >= 0), "indentation(): negative level"
|
101
|
-
return oneIndent.repeat(level)
|
102
|
-
|
103
|
-
# ---------------------------------------------------------------------------
|
104
|
-
# isUndented - true iff indentLevel(line) == 0
|
105
|
-
|
106
|
-
export isUndented = (line) =>
|
107
|
-
|
108
|
-
assert isString(line), "non-string #{OL(line)}"
|
109
|
-
return notdefined(line.match(/^\s/))
|
110
|
-
|
111
|
-
# ---------------------------------------------------------------------------
|
112
|
-
# indented - add indentation to each string in a block or array
|
113
|
-
# - returns the same type as input, i.e. array or string
|
114
|
-
|
115
|
-
export indented = (input, level=1, oneIndent="\t") =>
|
116
|
-
|
117
|
-
# --- level can be a string, in which case it is
|
118
|
-
# pre-pended to each line of input
|
119
|
-
if isString(level)
|
120
|
-
if (level == '')
|
121
|
-
return input
|
122
|
-
toAdd = level
|
123
|
-
else if isInteger(level)
|
124
|
-
if (level == 0)
|
125
|
-
return input
|
126
|
-
assert (level > 0), "Invalid level #{OL(level)}"
|
127
|
-
toAdd = indentation(level, oneIndent)
|
128
|
-
else
|
129
|
-
croak "Invalid level #{OL(level)}"
|
130
|
-
|
131
|
-
# --- NOTE: toArray(input) just returns input if it's an array
|
132
|
-
# else it splits the string into an array of lines
|
133
|
-
lLines = []
|
134
|
-
for line in toArray(input)
|
135
|
-
if isEmpty(line)
|
136
|
-
lLines.push ''
|
137
|
-
else
|
138
|
-
lLines.push "#{toAdd}#{line}"
|
139
|
-
|
140
|
-
if isArray(input)
|
141
|
-
return lLines
|
142
|
-
else if isString(input)
|
143
|
-
return toBlock(lLines)
|
144
|
-
croak "Invalid input; #{OL(input)}"
|
145
|
-
|
146
|
-
# ---------------------------------------------------------------------------
|
147
|
-
# undented - string with 1st line indentation removed for each line
|
148
|
-
# - ignore leading empty lines
|
149
|
-
# - returns same type as text, i.e. either string or array
|
150
|
-
|
151
|
-
export undented = (input) =>
|
152
|
-
|
153
|
-
# --- If a string, convert to an array
|
154
|
-
if isString(input)
|
155
|
-
lLines = toArray(input)
|
156
|
-
else if isArray(input)
|
157
|
-
lLines = input
|
158
|
-
else
|
159
|
-
croak "input not a string or array"
|
160
|
-
|
161
|
-
# --- Remove leading blank lines
|
162
|
-
while (lLines.length > 0) && isEmpty(lLines[0])
|
163
|
-
lLines.shift() # remove
|
164
|
-
|
165
|
-
if (lLines.length == 0)
|
166
|
-
if isString(input)
|
167
|
-
return ''
|
168
|
-
else
|
169
|
-
return []
|
170
|
-
|
171
|
-
# --- determine what to remove from beginning of each line
|
172
|
-
lMatches = lLines[0].match(/^\s*/)
|
173
|
-
toRemove = lMatches[0]
|
174
|
-
nToRemove = toRemove.length
|
175
|
-
if (nToRemove > 0)
|
176
|
-
lLines = lLines.map( (line) =>
|
177
|
-
if isEmpty(line)
|
178
|
-
return ''
|
179
|
-
else
|
180
|
-
assert (line.indexOf(toRemove)==0),
|
181
|
-
"can't remove #{OL(toRemove)} from #{OL(line)}"
|
182
|
-
return line.substr(nToRemove)
|
183
|
-
)
|
184
|
-
|
185
|
-
if isString(input)
|
186
|
-
return toBlock(lLines)
|
187
|
-
else
|
188
|
-
return lLines
|
189
|
-
|
190
|
-
# ---------------------------------------------------------------------------
|
191
|
-
# enclose - indent text, surround with pre and post
|
192
|
-
|
193
|
-
export enclose = (text, pre, post, oneIndent="\t") =>
|
194
|
-
|
195
|
-
return toBlock([
|
196
|
-
pre
|
197
|
-
indented(text, 1, oneIndent)
|
198
|
-
post
|
199
|
-
])
|
package/src/lib/indent.js
DELETED
@@ -1,216 +0,0 @@
|
|
1
|
-
// Generated by CoffeeScript 2.7.0
|
2
|
-
// indent.coffee
|
3
|
-
import {
|
4
|
-
assert,
|
5
|
-
croak
|
6
|
-
} from '@jdeighan/base-utils/exceptions';
|
7
|
-
|
8
|
-
import {
|
9
|
-
undef,
|
10
|
-
defined,
|
11
|
-
notdefined,
|
12
|
-
toArray,
|
13
|
-
toBlock,
|
14
|
-
OL,
|
15
|
-
isInteger,
|
16
|
-
isString,
|
17
|
-
isArray,
|
18
|
-
isEmpty,
|
19
|
-
rtrim
|
20
|
-
} from '@jdeighan/base-utils';
|
21
|
-
|
22
|
-
// ---------------------------------------------------------------------------
|
23
|
-
export var getOneIndent = (str) => {
|
24
|
-
var lMatches;
|
25
|
-
if ((lMatches = str.match(/^\t+(?:\S|$)/))) {
|
26
|
-
return "\t";
|
27
|
-
} else if ((lMatches = str.match(/^(\x20+)(?:\S|$)/))) { // space char
|
28
|
-
return lMatches[1];
|
29
|
-
}
|
30
|
-
assert(notdefined(str.match(/^\s/)), "Mixed indentation types");
|
31
|
-
return undef;
|
32
|
-
};
|
33
|
-
|
34
|
-
// ---------------------------------------------------------------------------
|
35
|
-
export var splitPrefix = (line) => {
|
36
|
-
var lMatches;
|
37
|
-
assert(isString(line), `non-string ${OL(line)}`);
|
38
|
-
line = rtrim(line);
|
39
|
-
lMatches = line.match(/^(\s*)(.*)$/);
|
40
|
-
return [lMatches[1], lMatches[2]];
|
41
|
-
};
|
42
|
-
|
43
|
-
// ---------------------------------------------------------------------------
|
44
|
-
// splitLine - separate a line into [level, line]
|
45
|
-
export var splitLine = (line, oneIndent = undef) => {
|
46
|
-
var prefix, str;
|
47
|
-
[prefix, str] = splitPrefix(line);
|
48
|
-
return [indentLevel(prefix, oneIndent), str];
|
49
|
-
};
|
50
|
-
|
51
|
-
// ---------------------------------------------------------------------------
|
52
|
-
// indentLevel - determine indent level of a string
|
53
|
-
// it's OK if the string is ONLY indentation
|
54
|
-
export var indentLevel = (line, oneIndent = undef) => {
|
55
|
-
var i, lMatches, len, level, nSpaces, nTabs, prefix, prefixLen, ref, str;
|
56
|
-
assert(isString(line), "not a string");
|
57
|
-
// --- This will always match, and it's greedy
|
58
|
-
if (lMatches = line.match(/^\s*/)) {
|
59
|
-
prefix = lMatches[0];
|
60
|
-
prefixLen = prefix.length;
|
61
|
-
}
|
62
|
-
if (prefixLen === 0) {
|
63
|
-
return 0;
|
64
|
-
}
|
65
|
-
// --- Match \t* followed by \x20* (error if no match)
|
66
|
-
if (lMatches = prefix.match(/(\t*)(\x20*)/)) {
|
67
|
-
nTabs = lMatches[1].length;
|
68
|
-
nSpaces = lMatches[2].length;
|
69
|
-
} else {
|
70
|
-
croak("Invalid mix of TABs and spaces");
|
71
|
-
}
|
72
|
-
// --- oneIndent must be one of:
|
73
|
-
// undef
|
74
|
-
// a single TAB character
|
75
|
-
// some number of space characters
|
76
|
-
switch (oneIndent) {
|
77
|
-
case undef:
|
78
|
-
if (nTabs > 0) {
|
79
|
-
level = nTabs; // there may also be spaces, but we ignore them
|
80
|
-
oneIndent = "\t"; // may be used at end
|
81
|
-
} else {
|
82
|
-
assert(nSpaces > 0, "There must be TABS or spaces");
|
83
|
-
level = 1;
|
84
|
-
oneIndent = ' '.repeat(nSpaces); // may be used at end
|
85
|
-
}
|
86
|
-
break;
|
87
|
-
case "\t":
|
88
|
-
assert(nTabs > 0, "Expecting TAB indentation, found spaces");
|
89
|
-
// --- NOTE: there may be spaces, but they're not indentation
|
90
|
-
level = nTabs;
|
91
|
-
break;
|
92
|
-
default:
|
93
|
-
// --- oneIndent must be all space chars
|
94
|
-
assert(nTabs === 0, `Indentation has TABs but oneIndent = ${OL(oneIndent)}`);
|
95
|
-
assert(nSpaces % oneIndent.length === 0, `prefix ${OL(prefix)} not a mult of ${OL(oneIndent)}`);
|
96
|
-
level = nSpaces / oneIndent.length;
|
97
|
-
}
|
98
|
-
// --- If a block, i.e. multi-line string, then all lines must be
|
99
|
-
// at least at this level
|
100
|
-
if (line.indexOf("\n") >= 0) {
|
101
|
-
ref = toArray(line);
|
102
|
-
for (i = 0, len = ref.length; i < len; i++) {
|
103
|
-
str = ref[i];
|
104
|
-
assert(indentLevel(str, oneIndent) >= level, `indentLevel of ${OL(line)} can't be found`);
|
105
|
-
}
|
106
|
-
}
|
107
|
-
return level;
|
108
|
-
};
|
109
|
-
|
110
|
-
// ---------------------------------------------------------------------------
|
111
|
-
// indentation - return appropriate indentation string for given level
|
112
|
-
// export only to allow unit testing
|
113
|
-
export var indentation = (level, oneIndent = "\t") => {
|
114
|
-
assert(level >= 0, "indentation(): negative level");
|
115
|
-
return oneIndent.repeat(level);
|
116
|
-
};
|
117
|
-
|
118
|
-
// ---------------------------------------------------------------------------
|
119
|
-
// isUndented - true iff indentLevel(line) == 0
|
120
|
-
export var isUndented = (line) => {
|
121
|
-
assert(isString(line), `non-string ${OL(line)}`);
|
122
|
-
return notdefined(line.match(/^\s/));
|
123
|
-
};
|
124
|
-
|
125
|
-
// ---------------------------------------------------------------------------
|
126
|
-
// indented - add indentation to each string in a block or array
|
127
|
-
// - returns the same type as input, i.e. array or string
|
128
|
-
export var indented = (input, level = 1, oneIndent = "\t") => {
|
129
|
-
var i, lLines, len, line, ref, toAdd;
|
130
|
-
// --- level can be a string, in which case it is
|
131
|
-
// pre-pended to each line of input
|
132
|
-
if (isString(level)) {
|
133
|
-
if (level === '') {
|
134
|
-
return input;
|
135
|
-
}
|
136
|
-
toAdd = level;
|
137
|
-
} else if (isInteger(level)) {
|
138
|
-
if (level === 0) {
|
139
|
-
return input;
|
140
|
-
}
|
141
|
-
assert(level > 0, `Invalid level ${OL(level)}`);
|
142
|
-
toAdd = indentation(level, oneIndent);
|
143
|
-
} else {
|
144
|
-
croak(`Invalid level ${OL(level)}`);
|
145
|
-
}
|
146
|
-
// --- NOTE: toArray(input) just returns input if it's an array
|
147
|
-
// else it splits the string into an array of lines
|
148
|
-
lLines = [];
|
149
|
-
ref = toArray(input);
|
150
|
-
for (i = 0, len = ref.length; i < len; i++) {
|
151
|
-
line = ref[i];
|
152
|
-
if (isEmpty(line)) {
|
153
|
-
lLines.push('');
|
154
|
-
} else {
|
155
|
-
lLines.push(`${toAdd}${line}`);
|
156
|
-
}
|
157
|
-
}
|
158
|
-
if (isArray(input)) {
|
159
|
-
return lLines;
|
160
|
-
} else if (isString(input)) {
|
161
|
-
return toBlock(lLines);
|
162
|
-
}
|
163
|
-
return croak(`Invalid input; ${OL(input)}`);
|
164
|
-
};
|
165
|
-
|
166
|
-
// ---------------------------------------------------------------------------
|
167
|
-
// undented - string with 1st line indentation removed for each line
|
168
|
-
// - ignore leading empty lines
|
169
|
-
// - returns same type as text, i.e. either string or array
|
170
|
-
export var undented = (input) => {
|
171
|
-
var lLines, lMatches, nToRemove, toRemove;
|
172
|
-
// --- If a string, convert to an array
|
173
|
-
if (isString(input)) {
|
174
|
-
lLines = toArray(input);
|
175
|
-
} else if (isArray(input)) {
|
176
|
-
lLines = input;
|
177
|
-
} else {
|
178
|
-
croak("input not a string or array");
|
179
|
-
}
|
180
|
-
// --- Remove leading blank lines
|
181
|
-
while ((lLines.length > 0) && isEmpty(lLines[0])) {
|
182
|
-
lLines.shift(); // remove
|
183
|
-
}
|
184
|
-
if (lLines.length === 0) {
|
185
|
-
if (isString(input)) {
|
186
|
-
return '';
|
187
|
-
} else {
|
188
|
-
return [];
|
189
|
-
}
|
190
|
-
}
|
191
|
-
// --- determine what to remove from beginning of each line
|
192
|
-
lMatches = lLines[0].match(/^\s*/);
|
193
|
-
toRemove = lMatches[0];
|
194
|
-
nToRemove = toRemove.length;
|
195
|
-
if (nToRemove > 0) {
|
196
|
-
lLines = lLines.map((line) => {
|
197
|
-
if (isEmpty(line)) {
|
198
|
-
return '';
|
199
|
-
} else {
|
200
|
-
assert(line.indexOf(toRemove) === 0, `can't remove ${OL(toRemove)} from ${OL(line)}`);
|
201
|
-
return line.substr(nToRemove);
|
202
|
-
}
|
203
|
-
});
|
204
|
-
}
|
205
|
-
if (isString(input)) {
|
206
|
-
return toBlock(lLines);
|
207
|
-
} else {
|
208
|
-
return lLines;
|
209
|
-
}
|
210
|
-
};
|
211
|
-
|
212
|
-
// ---------------------------------------------------------------------------
|
213
|
-
// enclose - indent text, surround with pre and post
|
214
|
-
export var enclose = (text, pre, post, oneIndent = "\t") => {
|
215
|
-
return toBlock([pre, indented(text, 1, oneIndent), post]);
|
216
|
-
};
|