@jdeighan/coffee-utils 10.0.1 → 10.0.4
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +2 -1
- package/src/SectionMap.coffee +19 -11
- package/src/SectionMap.js +19 -12
- package/src/block_utils.coffee +1 -1
- package/src/block_utils.js +2 -1
- package/src/html_utils.coffee +217 -0
- package/src/html_utils.js +222 -0
- package/src/indent_utils.coffee +0 -11
- package/src/indent_utils.js +0 -6
- package/src/log_utils.coffee +6 -1
- package/src/log_utils.js +8 -2
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@jdeighan/coffee-utils",
|
3
3
|
"type": "module",
|
4
|
-
"version": "10.0.
|
4
|
+
"version": "10.0.4",
|
5
5
|
"description": "A set of utility functions for CoffeeScript",
|
6
6
|
"main": "coffee_utils.js",
|
7
7
|
"exports": {
|
@@ -12,6 +12,7 @@
|
|
12
12
|
"./log": "./src/log_utils.js",
|
13
13
|
"./block": "./src/block_utils.js",
|
14
14
|
"./indent": "./src/indent_utils.js",
|
15
|
+
"./html": "./src/html_utils.js",
|
15
16
|
"./stack": "./src/call_stack.js",
|
16
17
|
"./debug": "./src/debug_utils.js",
|
17
18
|
"./arrow": "./src/arrow.js",
|
package/src/SectionMap.coffee
CHANGED
@@ -97,33 +97,41 @@ export class SectionMap
|
|
97
97
|
hReplacers = desc
|
98
98
|
desc = @lSectionTree
|
99
99
|
else if notdefined(desc)
|
100
|
+
debug "desc is entire tree"
|
100
101
|
desc = @lSectionTree
|
101
102
|
|
102
103
|
if isArray(desc)
|
104
|
+
debug "item is an array"
|
103
105
|
lBlocks = []
|
104
106
|
setName = undef
|
105
107
|
for item in desc
|
106
108
|
subBlock = undef
|
107
|
-
if
|
108
|
-
|
109
|
-
else if isSectionName(item)
|
110
|
-
subBlock = @getBlock(item, hReplacers)
|
111
|
-
else if isSetName(item)
|
109
|
+
if isSetName(item)
|
110
|
+
debug "set name is #{item}"
|
112
111
|
setName = item
|
113
|
-
else if
|
114
|
-
subBlock = item
|
112
|
+
else if isSectionName(item) || isArray(item)
|
113
|
+
subBlock = @getBlock(item, hReplacers)
|
114
|
+
if defined(subBlock)
|
115
|
+
debug "add subBlock", subBlock
|
116
|
+
lBlocks.push subBlock
|
117
|
+
else
|
118
|
+
debug "subBlock is undef"
|
119
|
+
else if isString(item) && nonEmpty(item)
|
120
|
+
debug "add string", item
|
121
|
+
lBlocks.push item
|
115
122
|
else
|
116
123
|
croak "Bad item: #{OL(item)}"
|
117
|
-
|
118
|
-
lBlocks.push subBlock
|
124
|
+
|
119
125
|
block = arrayToBlock(lBlocks)
|
126
|
+
debug "block is", block
|
120
127
|
if defined(setName)
|
121
128
|
if defined(proc = hReplacers[setName])
|
122
|
-
debug "REPLACE #{setName}"
|
123
129
|
block = proc(block)
|
130
|
+
debug "REPLACE #{setName} with", block
|
124
131
|
else
|
125
132
|
debug "NO REPLACER for #{setName}"
|
126
133
|
else if isSectionName(desc)
|
134
|
+
debug "item is a section name"
|
127
135
|
block = @section(desc).getBlock()
|
128
136
|
if defined(proc = hReplacers[desc])
|
129
137
|
debug "REPLACE #{desc}"
|
@@ -131,7 +139,7 @@ export class SectionMap
|
|
131
139
|
else
|
132
140
|
debug "NO REPLACER for #{desc}"
|
133
141
|
else if isSetName(desc)
|
134
|
-
|
142
|
+
debug "item is a set name"
|
135
143
|
block = @getBlock(@hSets[desc], hReplacers)
|
136
144
|
else
|
137
145
|
croak "Bad 1st arg: #{OL(desc)}"
|
package/src/SectionMap.js
CHANGED
@@ -126,39 +126,46 @@ export var SectionMap = class SectionMap {
|
|
126
126
|
hReplacers = desc;
|
127
127
|
desc = this.lSectionTree;
|
128
128
|
} else if (notdefined(desc)) {
|
129
|
+
debug("desc is entire tree");
|
129
130
|
desc = this.lSectionTree;
|
130
131
|
}
|
131
132
|
if (isArray(desc)) {
|
133
|
+
debug("item is an array");
|
132
134
|
lBlocks = [];
|
133
135
|
setName = undef;
|
134
136
|
for (i = 0, len = desc.length; i < len; i++) {
|
135
137
|
item = desc[i];
|
136
138
|
subBlock = undef;
|
137
|
-
if (
|
138
|
-
|
139
|
-
} else if (isSectionName(item)) {
|
140
|
-
subBlock = this.getBlock(item, hReplacers);
|
141
|
-
} else if (isSetName(item)) {
|
139
|
+
if (isSetName(item)) {
|
140
|
+
debug(`set name is ${item}`);
|
142
141
|
setName = item;
|
143
|
-
} else if (
|
144
|
-
subBlock = item;
|
142
|
+
} else if (isSectionName(item) || isArray(item)) {
|
143
|
+
subBlock = this.getBlock(item, hReplacers);
|
144
|
+
if (defined(subBlock)) {
|
145
|
+
debug("add subBlock", subBlock);
|
146
|
+
lBlocks.push(subBlock);
|
147
|
+
} else {
|
148
|
+
debug("subBlock is undef");
|
149
|
+
}
|
150
|
+
} else if (isString(item) && nonEmpty(item)) {
|
151
|
+
debug("add string", item);
|
152
|
+
lBlocks.push(item);
|
145
153
|
} else {
|
146
154
|
croak(`Bad item: ${OL(item)}`);
|
147
155
|
}
|
148
|
-
if (defined(subBlock)) {
|
149
|
-
lBlocks.push(subBlock);
|
150
|
-
}
|
151
156
|
}
|
152
157
|
block = arrayToBlock(lBlocks);
|
158
|
+
debug("block is", block);
|
153
159
|
if (defined(setName)) {
|
154
160
|
if (defined(proc = hReplacers[setName])) {
|
155
|
-
debug(`REPLACE ${setName}`);
|
156
161
|
block = proc(block);
|
162
|
+
debug(`REPLACE ${setName} with`, block);
|
157
163
|
} else {
|
158
164
|
debug(`NO REPLACER for ${setName}`);
|
159
165
|
}
|
160
166
|
}
|
161
167
|
} else if (isSectionName(desc)) {
|
168
|
+
debug("item is a section name");
|
162
169
|
block = this.section(desc).getBlock();
|
163
170
|
if (defined(proc = hReplacers[desc])) {
|
164
171
|
debug(`REPLACE ${desc}`);
|
@@ -167,7 +174,7 @@ export var SectionMap = class SectionMap {
|
|
167
174
|
debug(`NO REPLACER for ${desc}`);
|
168
175
|
}
|
169
176
|
} else if (isSetName(desc)) {
|
170
|
-
|
177
|
+
debug("item is a set name");
|
171
178
|
block = this.getBlock(this.hSets[desc], hReplacers);
|
172
179
|
} else {
|
173
180
|
croak(`Bad 1st arg: ${OL(desc)}`);
|
package/src/block_utils.coffee
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
import fs from 'fs'
|
4
4
|
import readline from 'readline'
|
5
5
|
|
6
|
-
import {assert, error} from '@jdeighan/unit-tester/utils'
|
6
|
+
import {assert, error, croak} from '@jdeighan/unit-tester/utils'
|
7
7
|
import {
|
8
8
|
undef, defined, isEmpty, isString, isArray, nonEmpty, rtrim,
|
9
9
|
} from '@jdeighan/coffee-utils'
|
package/src/block_utils.js
CHANGED
@@ -0,0 +1,217 @@
|
|
1
|
+
# html_utils.coffee
|
2
|
+
|
3
|
+
import {assert, croak} from '@jdeighan/unit-tester/utils'
|
4
|
+
import {
|
5
|
+
undef, pass, words, isEmpty, nonEmpty,
|
6
|
+
} from '@jdeighan/coffee-utils'
|
7
|
+
import {indented, enclose} from '@jdeighan/coffee-utils/indent'
|
8
|
+
import {arrayToBlock} from '@jdeighan/coffee-utils/block'
|
9
|
+
import {debug} from '@jdeighan/coffee-utils/debug'
|
10
|
+
|
11
|
+
hNoEnd = {}
|
12
|
+
for tagName in words('area base br col command embed hr img input' \
|
13
|
+
+ ' keygen link meta param source track wbr')
|
14
|
+
hNoEnd[tagName] = true
|
15
|
+
|
16
|
+
# ---------------------------------------------------------------------------
|
17
|
+
|
18
|
+
export parsetag = (line) ->
|
19
|
+
|
20
|
+
if lMatches = line.match(///^
|
21
|
+
(?:
|
22
|
+
([A-Za-z][A-Za-z0-9_]*) # variable name
|
23
|
+
\s*
|
24
|
+
=
|
25
|
+
\s*
|
26
|
+
)? # variable is optional
|
27
|
+
([A-Za-z][A-Za-z0-9_]*) # tag name
|
28
|
+
(?:
|
29
|
+
\:
|
30
|
+
( [a-z]+ )
|
31
|
+
)?
|
32
|
+
(\S*) # modifiers (class names, etc.)
|
33
|
+
\s*
|
34
|
+
(.*) # attributes & enclosed text
|
35
|
+
$///)
|
36
|
+
[_, varName, tagName, subtype, modifiers, rest] = lMatches
|
37
|
+
else
|
38
|
+
croak "parsetag(): Invalid HTML: '#{line}'"
|
39
|
+
|
40
|
+
# --- Handle classes - subtypes and added via .<class>
|
41
|
+
lClasses = []
|
42
|
+
if nonEmpty(subtype) && (tagName != 'svelte')
|
43
|
+
lClasses.push subtype
|
44
|
+
|
45
|
+
if modifiers
|
46
|
+
# --- currently, these are only class names
|
47
|
+
while lMatches = modifiers.match(///^
|
48
|
+
\. ([A-Za-z][A-Za-z0-9_]*)
|
49
|
+
///)
|
50
|
+
[all, className] = lMatches
|
51
|
+
lClasses.push className
|
52
|
+
modifiers = modifiers.substring(all.length)
|
53
|
+
if modifiers
|
54
|
+
croak "parsetag(): Invalid modifiers in '#{line}'"
|
55
|
+
|
56
|
+
# --- Handle attributes
|
57
|
+
hAttr = {} # { name: { value: <value>, quote: <quote> }, ... }
|
58
|
+
|
59
|
+
if varName
|
60
|
+
hAttr['bind:this'] = {value: varName, quote: '{'}
|
61
|
+
|
62
|
+
if (tagName == 'script') && (subtype == 'startup')
|
63
|
+
hAttr['context'] = {value: 'module', quote: '"'}
|
64
|
+
|
65
|
+
if rest
|
66
|
+
while lMatches = rest.match(///^
|
67
|
+
(?:
|
68
|
+
(?:
|
69
|
+
(?:
|
70
|
+
( bind | on ) # prefix
|
71
|
+
:
|
72
|
+
)?
|
73
|
+
([A-Za-z][A-Za-z0-9_]*) # attribute name
|
74
|
+
)
|
75
|
+
=
|
76
|
+
(?:
|
77
|
+
\{ ([^}]*) \} # attribute value
|
78
|
+
| " ([^"]*) "
|
79
|
+
| ' ([^']*) '
|
80
|
+
| ([^"'\s]+)
|
81
|
+
)
|
82
|
+
|
|
83
|
+
\{
|
84
|
+
([A-Za-z][A-Za-z0-9_]*)
|
85
|
+
\}
|
86
|
+
) \s*
|
87
|
+
///)
|
88
|
+
[all, prefix, attrName, br_val, dq_val, sq_val, uq_val, ident] = lMatches
|
89
|
+
if ident
|
90
|
+
hAttr[ident] = { value: ident, shorthand: true }
|
91
|
+
else
|
92
|
+
if br_val
|
93
|
+
value = br_val
|
94
|
+
quote = '{'
|
95
|
+
else
|
96
|
+
assert ! prefix?, "prefix requires use of {...}"
|
97
|
+
if dq_val
|
98
|
+
value = dq_val
|
99
|
+
quote = '"'
|
100
|
+
else if sq_val
|
101
|
+
value = sq_val
|
102
|
+
quote = "'"
|
103
|
+
else
|
104
|
+
value = uq_val
|
105
|
+
quote = ''
|
106
|
+
|
107
|
+
if prefix
|
108
|
+
attrName = "#{prefix}:#{attrName}"
|
109
|
+
|
110
|
+
if attrName == 'class'
|
111
|
+
for className in value.split(/\s+/)
|
112
|
+
lClasses.push className
|
113
|
+
else
|
114
|
+
if hAttr.attrName?
|
115
|
+
croak "parsetag(): Multiple attributes named '#{attrName}'"
|
116
|
+
hAttr[attrName] = { value, quote }
|
117
|
+
|
118
|
+
rest = rest.substring(all.length)
|
119
|
+
|
120
|
+
# --- The rest is contained text
|
121
|
+
rest = rest.trim()
|
122
|
+
if lMatches = rest.match(///^
|
123
|
+
['"]
|
124
|
+
(.*)
|
125
|
+
['"]
|
126
|
+
$///)
|
127
|
+
rest = lMatches[1]
|
128
|
+
|
129
|
+
# --- Add class attribute to hAttr if there are classes
|
130
|
+
if (lClasses.length > 0)
|
131
|
+
hAttr.class = {
|
132
|
+
value: lClasses.join(' '),
|
133
|
+
quote: '"',
|
134
|
+
}
|
135
|
+
|
136
|
+
# --- Build the return value
|
137
|
+
hToken = {
|
138
|
+
type: 'tag'
|
139
|
+
tagName
|
140
|
+
}
|
141
|
+
|
142
|
+
if subtype
|
143
|
+
hToken.subtype = subtype
|
144
|
+
hToken.orgtag = "#{tagName}:#{subtype}"
|
145
|
+
else
|
146
|
+
hToken.orgtag = tagName
|
147
|
+
|
148
|
+
# --- if tagName == 'svelte', set hToken.tagName to hToken.orgtag
|
149
|
+
if (tagName == 'svelte')
|
150
|
+
hToken.tagName = hToken.orgtag
|
151
|
+
|
152
|
+
if nonEmpty(hAttr)
|
153
|
+
hToken.hAttr = hAttr
|
154
|
+
|
155
|
+
# --- Is there contained text?
|
156
|
+
if rest
|
157
|
+
hToken.text = rest
|
158
|
+
|
159
|
+
return hToken
|
160
|
+
|
161
|
+
# ---------------------------------------------------------------------------
|
162
|
+
# --- export only for unit testing
|
163
|
+
|
164
|
+
export attrStr = (hAttr) ->
|
165
|
+
|
166
|
+
if ! hAttr
|
167
|
+
return ''
|
168
|
+
str = ''
|
169
|
+
for attrName in Object.getOwnPropertyNames(hAttr)
|
170
|
+
{value, quote, shorthand} = hAttr[attrName]
|
171
|
+
if shorthand
|
172
|
+
str += " {#{value}}"
|
173
|
+
else
|
174
|
+
if quote == '{'
|
175
|
+
bquote = '{'
|
176
|
+
equote = '}'
|
177
|
+
else
|
178
|
+
bquote = equote = quote
|
179
|
+
str += " #{attrName}=#{bquote}#{value}#{equote}"
|
180
|
+
return str
|
181
|
+
|
182
|
+
# ---------------------------------------------------------------------------
|
183
|
+
|
184
|
+
export tag2str = (hToken, type='begin') ->
|
185
|
+
|
186
|
+
{tagName, hAttr} = hToken
|
187
|
+
if (type == 'begin')
|
188
|
+
str = "<#{tagName}" # build the string bit by bit
|
189
|
+
if nonEmpty(hAttr)
|
190
|
+
str += attrStr(hAttr)
|
191
|
+
str += '>'
|
192
|
+
return str
|
193
|
+
else if (type == 'end')
|
194
|
+
if hNoEnd[tagName]
|
195
|
+
return undef
|
196
|
+
else
|
197
|
+
return "</#{tagName}>"
|
198
|
+
else
|
199
|
+
croak "type must be 'begin' or 'end'"
|
200
|
+
|
201
|
+
# ---------------------------------------------------------------------------
|
202
|
+
# elem - indent text, surround with HTML tags
|
203
|
+
|
204
|
+
export elem = (tagName, hAttr=undef, text=undef, oneIndent="\t") ->
|
205
|
+
|
206
|
+
if isEmpty(text)
|
207
|
+
return undef
|
208
|
+
hToken = {
|
209
|
+
tagName
|
210
|
+
hAttr
|
211
|
+
text
|
212
|
+
}
|
213
|
+
return arrayToBlock([
|
214
|
+
tag2str(hToken, 'begin')
|
215
|
+
indented(text, 1, oneIndent)
|
216
|
+
tag2str(hToken, 'end')
|
217
|
+
])
|
@@ -0,0 +1,222 @@
|
|
1
|
+
// Generated by CoffeeScript 2.7.0
|
2
|
+
// html_utils.coffee
|
3
|
+
var hNoEnd, i, len, ref, tagName;
|
4
|
+
|
5
|
+
import {
|
6
|
+
assert,
|
7
|
+
croak
|
8
|
+
} from '@jdeighan/unit-tester/utils';
|
9
|
+
|
10
|
+
import {
|
11
|
+
undef,
|
12
|
+
pass,
|
13
|
+
words,
|
14
|
+
isEmpty,
|
15
|
+
nonEmpty
|
16
|
+
} from '@jdeighan/coffee-utils';
|
17
|
+
|
18
|
+
import {
|
19
|
+
indented,
|
20
|
+
enclose
|
21
|
+
} from '@jdeighan/coffee-utils/indent';
|
22
|
+
|
23
|
+
import {
|
24
|
+
arrayToBlock
|
25
|
+
} from '@jdeighan/coffee-utils/block';
|
26
|
+
|
27
|
+
import {
|
28
|
+
debug
|
29
|
+
} from '@jdeighan/coffee-utils/debug';
|
30
|
+
|
31
|
+
hNoEnd = {};
|
32
|
+
|
33
|
+
ref = words('area base br col command embed hr img input' + ' keygen link meta param source track wbr');
|
34
|
+
for (i = 0, len = ref.length; i < len; i++) {
|
35
|
+
tagName = ref[i];
|
36
|
+
hNoEnd[tagName] = true;
|
37
|
+
}
|
38
|
+
|
39
|
+
// ---------------------------------------------------------------------------
|
40
|
+
export var parsetag = function(line) {
|
41
|
+
var _, all, attrName, br_val, className, dq_val, hAttr, hToken, ident, j, lClasses, lMatches, len1, modifiers, prefix, quote, ref1, rest, sq_val, subtype, uq_val, value, varName;
|
42
|
+
if (lMatches = line.match(/^(?:([A-Za-z][A-Za-z0-9_]*)\s*=\s*)?([A-Za-z][A-Za-z0-9_]*)(?:\:([a-z]+))?(\S*)\s*(.*)$/)) { // variable name
|
43
|
+
// variable is optional
|
44
|
+
// tag name
|
45
|
+
// modifiers (class names, etc.)
|
46
|
+
// attributes & enclosed text
|
47
|
+
[_, varName, tagName, subtype, modifiers, rest] = lMatches;
|
48
|
+
} else {
|
49
|
+
croak(`parsetag(): Invalid HTML: '${line}'`);
|
50
|
+
}
|
51
|
+
// --- Handle classes - subtypes and added via .<class>
|
52
|
+
lClasses = [];
|
53
|
+
if (nonEmpty(subtype) && (tagName !== 'svelte')) {
|
54
|
+
lClasses.push(subtype);
|
55
|
+
}
|
56
|
+
if (modifiers) {
|
57
|
+
// --- currently, these are only class names
|
58
|
+
while (lMatches = modifiers.match(/^\.([A-Za-z][A-Za-z0-9_]*)/)) {
|
59
|
+
[all, className] = lMatches;
|
60
|
+
lClasses.push(className);
|
61
|
+
modifiers = modifiers.substring(all.length);
|
62
|
+
}
|
63
|
+
if (modifiers) {
|
64
|
+
croak(`parsetag(): Invalid modifiers in '${line}'`);
|
65
|
+
}
|
66
|
+
}
|
67
|
+
// --- Handle attributes
|
68
|
+
hAttr = {}; // { name: { value: <value>, quote: <quote> }, ... }
|
69
|
+
if (varName) {
|
70
|
+
hAttr['bind:this'] = {
|
71
|
+
value: varName,
|
72
|
+
quote: '{'
|
73
|
+
};
|
74
|
+
}
|
75
|
+
if ((tagName === 'script') && (subtype === 'startup')) {
|
76
|
+
hAttr['context'] = {
|
77
|
+
value: 'module',
|
78
|
+
quote: '"'
|
79
|
+
};
|
80
|
+
}
|
81
|
+
if (rest) {
|
82
|
+
while (lMatches = rest.match(/^(?:(?:(?:(bind|on):)?([A-Za-z][A-Za-z0-9_]*))=(?:\{([^}]*)\}|"([^"]*)"|'([^']*)'|([^"'\s]+))|\{([A-Za-z][A-Za-z0-9_]*)\})\s*/)) { // prefix
|
83
|
+
// attribute name
|
84
|
+
// attribute value
|
85
|
+
[all, prefix, attrName, br_val, dq_val, sq_val, uq_val, ident] = lMatches;
|
86
|
+
if (ident) {
|
87
|
+
hAttr[ident] = {
|
88
|
+
value: ident,
|
89
|
+
shorthand: true
|
90
|
+
};
|
91
|
+
} else {
|
92
|
+
if (br_val) {
|
93
|
+
value = br_val;
|
94
|
+
quote = '{';
|
95
|
+
} else {
|
96
|
+
assert(prefix == null, "prefix requires use of {...}");
|
97
|
+
if (dq_val) {
|
98
|
+
value = dq_val;
|
99
|
+
quote = '"';
|
100
|
+
} else if (sq_val) {
|
101
|
+
value = sq_val;
|
102
|
+
quote = "'";
|
103
|
+
} else {
|
104
|
+
value = uq_val;
|
105
|
+
quote = '';
|
106
|
+
}
|
107
|
+
}
|
108
|
+
if (prefix) {
|
109
|
+
attrName = `${prefix}:${attrName}`;
|
110
|
+
}
|
111
|
+
if (attrName === 'class') {
|
112
|
+
ref1 = value.split(/\s+/);
|
113
|
+
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
114
|
+
className = ref1[j];
|
115
|
+
lClasses.push(className);
|
116
|
+
}
|
117
|
+
} else {
|
118
|
+
if (hAttr.attrName != null) {
|
119
|
+
croak(`parsetag(): Multiple attributes named '${attrName}'`);
|
120
|
+
}
|
121
|
+
hAttr[attrName] = {value, quote};
|
122
|
+
}
|
123
|
+
}
|
124
|
+
rest = rest.substring(all.length);
|
125
|
+
}
|
126
|
+
}
|
127
|
+
// --- The rest is contained text
|
128
|
+
rest = rest.trim();
|
129
|
+
if (lMatches = rest.match(/^['"](.*)['"]$/)) {
|
130
|
+
rest = lMatches[1];
|
131
|
+
}
|
132
|
+
// --- Add class attribute to hAttr if there are classes
|
133
|
+
if (lClasses.length > 0) {
|
134
|
+
hAttr.class = {
|
135
|
+
value: lClasses.join(' '),
|
136
|
+
quote: '"'
|
137
|
+
};
|
138
|
+
}
|
139
|
+
// --- Build the return value
|
140
|
+
hToken = {
|
141
|
+
type: 'tag',
|
142
|
+
tagName
|
143
|
+
};
|
144
|
+
if (subtype) {
|
145
|
+
hToken.subtype = subtype;
|
146
|
+
hToken.orgtag = `${tagName}:${subtype}`;
|
147
|
+
} else {
|
148
|
+
hToken.orgtag = tagName;
|
149
|
+
}
|
150
|
+
// --- if tagName == 'svelte', set hToken.tagName to hToken.orgtag
|
151
|
+
if (tagName === 'svelte') {
|
152
|
+
hToken.tagName = hToken.orgtag;
|
153
|
+
}
|
154
|
+
if (nonEmpty(hAttr)) {
|
155
|
+
hToken.hAttr = hAttr;
|
156
|
+
}
|
157
|
+
// --- Is there contained text?
|
158
|
+
if (rest) {
|
159
|
+
hToken.text = rest;
|
160
|
+
}
|
161
|
+
return hToken;
|
162
|
+
};
|
163
|
+
|
164
|
+
// ---------------------------------------------------------------------------
|
165
|
+
// --- export only for unit testing
|
166
|
+
export var attrStr = function(hAttr) {
|
167
|
+
var attrName, bquote, equote, j, len1, quote, ref1, shorthand, str, value;
|
168
|
+
if (!hAttr) {
|
169
|
+
return '';
|
170
|
+
}
|
171
|
+
str = '';
|
172
|
+
ref1 = Object.getOwnPropertyNames(hAttr);
|
173
|
+
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
174
|
+
attrName = ref1[j];
|
175
|
+
({value, quote, shorthand} = hAttr[attrName]);
|
176
|
+
if (shorthand) {
|
177
|
+
str += ` {${value}}`;
|
178
|
+
} else {
|
179
|
+
if (quote === '{') {
|
180
|
+
bquote = '{';
|
181
|
+
equote = '}';
|
182
|
+
} else {
|
183
|
+
bquote = equote = quote;
|
184
|
+
}
|
185
|
+
str += ` ${attrName}=${bquote}${value}${equote}`;
|
186
|
+
}
|
187
|
+
}
|
188
|
+
return str;
|
189
|
+
};
|
190
|
+
|
191
|
+
// ---------------------------------------------------------------------------
|
192
|
+
export var tag2str = function(hToken, type = 'begin') {
|
193
|
+
var hAttr, str;
|
194
|
+
({tagName, hAttr} = hToken);
|
195
|
+
if (type === 'begin') {
|
196
|
+
str = `<${tagName}`;
|
197
|
+
if (nonEmpty(hAttr)) {
|
198
|
+
str += attrStr(hAttr);
|
199
|
+
}
|
200
|
+
str += '>';
|
201
|
+
return str;
|
202
|
+
} else if (type === 'end') {
|
203
|
+
if (hNoEnd[tagName]) {
|
204
|
+
return undef;
|
205
|
+
} else {
|
206
|
+
return `</${tagName}>`;
|
207
|
+
}
|
208
|
+
} else {
|
209
|
+
return croak("type must be 'begin' or 'end'");
|
210
|
+
}
|
211
|
+
};
|
212
|
+
|
213
|
+
// ---------------------------------------------------------------------------
|
214
|
+
// elem - indent text, surround with HTML tags
|
215
|
+
export var elem = function(tagName, hAttr = undef, text = undef, oneIndent = "\t") {
|
216
|
+
var hToken;
|
217
|
+
if (isEmpty(text)) {
|
218
|
+
return undef;
|
219
|
+
}
|
220
|
+
hToken = {tagName, hAttr, text};
|
221
|
+
return arrayToBlock([tag2str(hToken, 'begin'), indented(text, 1, oneIndent), tag2str(hToken, 'end')]);
|
222
|
+
};
|
package/src/indent_utils.coffee
CHANGED
@@ -164,14 +164,3 @@ export enclose = (text, pre, post, oneIndent="\t") ->
|
|
164
164
|
indented(text, 1, oneIndent)
|
165
165
|
post
|
166
166
|
])
|
167
|
-
|
168
|
-
# ---------------------------------------------------------------------------
|
169
|
-
# elem - indent text, surround with HTML tags
|
170
|
-
|
171
|
-
export elem = (text, tag, oneIndent="\t") ->
|
172
|
-
|
173
|
-
return arrayToBlock([
|
174
|
-
"<#{tag}>"
|
175
|
-
indented(text, 1, oneIndent)
|
176
|
-
"</#{tag}>"
|
177
|
-
])
|
package/src/indent_utils.js
CHANGED
@@ -187,9 +187,3 @@ export var untabify = function(str, numSpaces = 3) {
|
|
187
187
|
export var enclose = function(text, pre, post, oneIndent = "\t") {
|
188
188
|
return arrayToBlock([pre, indented(text, 1, oneIndent), post]);
|
189
189
|
};
|
190
|
-
|
191
|
-
// ---------------------------------------------------------------------------
|
192
|
-
// elem - indent text, surround with HTML tags
|
193
|
-
export var elem = function(text, tag, oneIndent = "\t") {
|
194
|
-
return arrayToBlock([`<${tag}>`, indented(text, 1, oneIndent), `</${tag}>`]);
|
195
|
-
};
|
package/src/log_utils.coffee
CHANGED
@@ -183,7 +183,12 @@ export logItem = (label, item, pre='', itemPre=undef) ->
|
|
183
183
|
putstr "#{pre}#{labelStr}#{item}"
|
184
184
|
else if isString(item)
|
185
185
|
if (item.length <= maxOneLine)
|
186
|
-
|
186
|
+
result = escapeStr(item)
|
187
|
+
hasApos = (result.indexOf("'") >= 0)
|
188
|
+
if hasApos
|
189
|
+
putstr "#{pre}#{labelStr}\"#{result}\""
|
190
|
+
else
|
191
|
+
putstr "#{pre}#{labelStr}'#{result}'"
|
187
192
|
else
|
188
193
|
if label
|
189
194
|
putstr "#{pre}#{label}:"
|
package/src/log_utils.js
CHANGED
@@ -184,7 +184,7 @@ export var logBareItem = function(item, pre = '') {
|
|
184
184
|
|
185
185
|
// ---------------------------------------------------------------------------
|
186
186
|
export var logItem = function(label, item, pre = '', itemPre = undef) {
|
187
|
-
var i, labelStr, len, ref, str;
|
187
|
+
var hasApos, i, labelStr, len, ref, result, str;
|
188
188
|
assert(isString(pre), `not a string: ${OL(pre)}`);
|
189
189
|
assert(isFunction(putstr), "putstr not properly set");
|
190
190
|
assert(!label || isString(label), "label a non-string");
|
@@ -207,7 +207,13 @@ export var logItem = function(label, item, pre = '', itemPre = undef) {
|
|
207
207
|
putstr(`${pre}${labelStr}${item}`);
|
208
208
|
} else if (isString(item)) {
|
209
209
|
if (item.length <= maxOneLine) {
|
210
|
-
|
210
|
+
result = escapeStr(item);
|
211
|
+
hasApos = result.indexOf("'") >= 0;
|
212
|
+
if (hasApos) {
|
213
|
+
putstr(`${pre}${labelStr}\"${result}\"`);
|
214
|
+
} else {
|
215
|
+
putstr(`${pre}${labelStr}'${result}'`);
|
216
|
+
}
|
211
217
|
} else {
|
212
218
|
if (label) {
|
213
219
|
putstr(`${pre}${label}:`);
|