@jdeighan/coffee-utils 14.0.31 → 14.0.33
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 +3 -3
- package/src/html.coffee +57 -1
- package/src/html.js +60 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jdeighan/coffee-utils",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "14.0.
|
|
4
|
+
"version": "14.0.33",
|
|
5
5
|
"description": "A set of utility functions for CoffeeScript",
|
|
6
6
|
"main": "coffee_utils.js",
|
|
7
7
|
"exports": {
|
|
@@ -45,14 +45,14 @@
|
|
|
45
45
|
},
|
|
46
46
|
"homepage": "https://github.com/johndeighan/coffee-utils#readme",
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@jdeighan/base-utils": "^4.0.
|
|
48
|
+
"@jdeighan/base-utils": "^4.0.19",
|
|
49
49
|
"cross-env": "^7.0.3",
|
|
50
50
|
"n-readlines": "^1.0.1",
|
|
51
51
|
"readline-sync": "^1.4.10",
|
|
52
52
|
"svelte": "^3.55.1"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@jdeighan/unit-tester": "^3.0.
|
|
55
|
+
"@jdeighan/unit-tester": "^3.0.41",
|
|
56
56
|
"ava": "^5.1.1"
|
|
57
57
|
}
|
|
58
58
|
}
|
package/src/html.coffee
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import {assert, croak} from '@jdeighan/base-utils/exceptions'
|
|
4
4
|
import {
|
|
5
|
-
undef, pass, words, isEmpty, nonEmpty, toBlock,
|
|
5
|
+
undef, pass, words, isEmpty, nonEmpty, toBlock, OL, getOptions,
|
|
6
6
|
} from '@jdeighan/base-utils'
|
|
7
|
+
import {dbgEnter, dbgReturn, dbg} from '@jdeighan/base-utils/debug'
|
|
7
8
|
import {indented} from '@jdeighan/coffee-utils/indent'
|
|
8
9
|
|
|
9
10
|
hNoEnd = {}
|
|
@@ -211,3 +212,58 @@ export elem = (tagName, hAttr=undef, text=undef, oneIndent="\t") =>
|
|
|
211
212
|
indented(text, 1, oneIndent)
|
|
212
213
|
tag2str(hToken, 'end')
|
|
213
214
|
])
|
|
215
|
+
|
|
216
|
+
# ---------------------------------------------------------------------------
|
|
217
|
+
|
|
218
|
+
export formatHTML = (html, hOptions={}) =>
|
|
219
|
+
|
|
220
|
+
dbgEnter 'formatHTML', html, hOptions
|
|
221
|
+
{oneIndent} = getOptions(hOptions, {
|
|
222
|
+
oneIndent: ' '
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
html = html.trim() # remove any leading/trailing whitespace
|
|
226
|
+
assert html.charAt(0) == '<', "Bad HTML, no < at start"
|
|
227
|
+
assert html.charAt(html.length-1) == '>', "Bad HTML, no > at end"
|
|
228
|
+
|
|
229
|
+
# --- Remove leading '<' and trailing '>'
|
|
230
|
+
html = html.substring(1, html.length-1)
|
|
231
|
+
|
|
232
|
+
hNoEndTag = {}
|
|
233
|
+
for tag in words("""
|
|
234
|
+
br hr img input link base
|
|
235
|
+
meta param area embed
|
|
236
|
+
col track source
|
|
237
|
+
""")
|
|
238
|
+
hNoEndTag[tag] = true
|
|
239
|
+
|
|
240
|
+
lParts = []
|
|
241
|
+
level = 0
|
|
242
|
+
|
|
243
|
+
for elem in html.split(/>\s*</)
|
|
244
|
+
dbg "ELEM: #{OL(elem)}"
|
|
245
|
+
[_, endMarker, tagName, rest] = elem.match(///^
|
|
246
|
+
(\/)? # possible end tag
|
|
247
|
+
([A-Za-z][A-Za-z0-9-]*) # tag name
|
|
248
|
+
(.*) # everything else
|
|
249
|
+
$///)
|
|
250
|
+
if endMarker
|
|
251
|
+
dbg " TAG: #{OL(tagName)} - END MARKER"
|
|
252
|
+
else
|
|
253
|
+
dbg " TAG: #{OL(tagName)} - NO END MARKER"
|
|
254
|
+
|
|
255
|
+
if endMarker && (level > 0)
|
|
256
|
+
# --- If end tag, reduce level
|
|
257
|
+
dbg " reduce level #{level} to #{level-1}"
|
|
258
|
+
level -= 1
|
|
259
|
+
|
|
260
|
+
dbg " ADD #{OL(elem)} at level #{level}"
|
|
261
|
+
lParts.push oneIndent.repeat(level), "<#{elem}>\n"
|
|
262
|
+
|
|
263
|
+
if ! endMarker && ! hNoEndTag[tagName] && !rest.endsWith('/'+tagName)
|
|
264
|
+
dbg " inc level #{level} to #{level+1}"
|
|
265
|
+
level += 1
|
|
266
|
+
|
|
267
|
+
result = lParts.join('').trim()
|
|
268
|
+
dbgReturn 'formatHTML', result
|
|
269
|
+
return result
|
package/src/html.js
CHANGED
|
@@ -13,9 +13,17 @@ import {
|
|
|
13
13
|
words,
|
|
14
14
|
isEmpty,
|
|
15
15
|
nonEmpty,
|
|
16
|
-
toBlock
|
|
16
|
+
toBlock,
|
|
17
|
+
OL,
|
|
18
|
+
getOptions
|
|
17
19
|
} from '@jdeighan/base-utils';
|
|
18
20
|
|
|
21
|
+
import {
|
|
22
|
+
dbgEnter,
|
|
23
|
+
dbgReturn,
|
|
24
|
+
dbg
|
|
25
|
+
} from '@jdeighan/base-utils/debug';
|
|
26
|
+
|
|
19
27
|
import {
|
|
20
28
|
indented
|
|
21
29
|
} from '@jdeighan/coffee-utils/indent';
|
|
@@ -214,3 +222,54 @@ export var elem = (tagName, hAttr = undef, text = undef, oneIndent = "\t") => {
|
|
|
214
222
|
return toBlock([tag2str(hToken, 'begin'), indented(text, 1, oneIndent), tag2str(hToken, 'end')]);
|
|
215
223
|
}
|
|
216
224
|
};
|
|
225
|
+
|
|
226
|
+
// ---------------------------------------------------------------------------
|
|
227
|
+
export var formatHTML = (html, hOptions = {}) => {
|
|
228
|
+
var _, endMarker, hNoEndTag, j, k, lParts, len1, len2, level, oneIndent, ref1, ref2, rest, result, tag;
|
|
229
|
+
dbgEnter('formatHTML', html, hOptions);
|
|
230
|
+
({oneIndent} = getOptions(hOptions, {
|
|
231
|
+
oneIndent: ' '
|
|
232
|
+
}));
|
|
233
|
+
html = html.trim(); // remove any leading/trailing whitespace
|
|
234
|
+
assert(html.charAt(0) === '<', "Bad HTML, no < at start");
|
|
235
|
+
assert(html.charAt(html.length - 1) === '>', "Bad HTML, no > at end");
|
|
236
|
+
// --- Remove leading '<' and trailing '>'
|
|
237
|
+
html = html.substring(1, html.length - 1);
|
|
238
|
+
hNoEndTag = {};
|
|
239
|
+
ref1 = words(`br hr img input link base
|
|
240
|
+
meta param area embed
|
|
241
|
+
col track source`);
|
|
242
|
+
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
|
243
|
+
tag = ref1[j];
|
|
244
|
+
hNoEndTag[tag] = true;
|
|
245
|
+
}
|
|
246
|
+
lParts = [];
|
|
247
|
+
level = 0;
|
|
248
|
+
ref2 = html.split(/>\s*</);
|
|
249
|
+
for (k = 0, len2 = ref2.length; k < len2; k++) {
|
|
250
|
+
elem = ref2[k];
|
|
251
|
+
dbg(`ELEM: ${OL(elem)}`);
|
|
252
|
+
[_, endMarker, tagName, rest] = elem.match(/^(\/)?([A-Za-z][A-Za-z0-9-]*)(.*)$/); // possible end tag
|
|
253
|
+
// tag name
|
|
254
|
+
// everything else
|
|
255
|
+
if (endMarker) {
|
|
256
|
+
dbg(` TAG: ${OL(tagName)} - END MARKER`);
|
|
257
|
+
} else {
|
|
258
|
+
dbg(` TAG: ${OL(tagName)} - NO END MARKER`);
|
|
259
|
+
}
|
|
260
|
+
if (endMarker && (level > 0)) {
|
|
261
|
+
// --- If end tag, reduce level
|
|
262
|
+
dbg(` reduce level ${level} to ${level - 1}`);
|
|
263
|
+
level -= 1;
|
|
264
|
+
}
|
|
265
|
+
dbg(` ADD ${OL(elem)} at level ${level}`);
|
|
266
|
+
lParts.push(oneIndent.repeat(level), `<${elem}>\n`);
|
|
267
|
+
if (!endMarker && !hNoEndTag[tagName] && !rest.endsWith('/' + tagName)) {
|
|
268
|
+
dbg(` inc level ${level} to ${level + 1}`);
|
|
269
|
+
level += 1;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
result = lParts.join('').trim();
|
|
273
|
+
dbgReturn('formatHTML', result);
|
|
274
|
+
return result;
|
|
275
|
+
};
|