weml-monaco 0.4.0 → 0.4.3
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/CHANGELOG.md +37 -0
- package/dist/index.cjs +449 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.global.js +61 -61
- package/dist/index.mjs +449 -61
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6106,21 +6106,47 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6106
6106
|
"a",
|
|
6107
6107
|
"w-anchor",
|
|
6108
6108
|
"w-sent",
|
|
6109
|
-
"w-page"
|
|
6109
|
+
"w-page",
|
|
6110
|
+
"w-color"
|
|
6110
6111
|
]);
|
|
6111
|
-
var VOID_HTML_ELEMENTS = /* @__PURE__ */ new Set([
|
|
6112
|
-
|
|
6113
|
-
|
|
6112
|
+
var VOID_HTML_ELEMENTS = /* @__PURE__ */ new Set([
|
|
6113
|
+
"area",
|
|
6114
|
+
"base",
|
|
6115
|
+
"br",
|
|
6116
|
+
"col",
|
|
6117
|
+
"embed",
|
|
6118
|
+
"hr",
|
|
6119
|
+
"img",
|
|
6120
|
+
"input",
|
|
6121
|
+
"link",
|
|
6122
|
+
"meta",
|
|
6123
|
+
"source",
|
|
6124
|
+
"track",
|
|
6125
|
+
"wbr",
|
|
6126
|
+
"param"
|
|
6127
|
+
]);
|
|
6128
|
+
var EMPTY_TEXT_WRAPPERS = /* @__PURE__ */ new Set([
|
|
6129
|
+
"w-format",
|
|
6130
|
+
"w-lang",
|
|
6131
|
+
"w-color",
|
|
6132
|
+
"w-non-egw",
|
|
6133
|
+
"w-sent"
|
|
6134
|
+
]);
|
|
6135
|
+
var ENTITY_RE2 = /&(#[xX][0-9a-fA-F]+|#[0-9]+|[a-zA-Z][a-zA-Z0-9]*);?/g;
|
|
6114
6136
|
var PH_OPEN = "\uE000";
|
|
6115
6137
|
var PH_CLOSE = "\uE001";
|
|
6116
|
-
var
|
|
6117
|
-
var
|
|
6138
|
+
var VOID_ELEMENTS = VOID_HTML_ELEMENTS;
|
|
6139
|
+
var SPACE_SEPARATED_ATTRIBUTES = /* @__PURE__ */ new Set(["class", "headers", "rel", "rev"]);
|
|
6118
6140
|
var WHITE_SPACE = /* @__PURE__ */ new Set([
|
|
6119
6141
|
9,
|
|
6120
6142
|
10,
|
|
6121
6143
|
11,
|
|
6122
6144
|
12,
|
|
6123
6145
|
13,
|
|
6146
|
+
28,
|
|
6147
|
+
29,
|
|
6148
|
+
30,
|
|
6149
|
+
31,
|
|
6124
6150
|
32,
|
|
6125
6151
|
133,
|
|
6126
6152
|
160,
|
|
@@ -6140,40 +6166,193 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6140
6166
|
8233,
|
|
6141
6167
|
8239,
|
|
6142
6168
|
8287,
|
|
6143
|
-
12288
|
|
6169
|
+
12288,
|
|
6170
|
+
65279
|
|
6144
6171
|
]);
|
|
6145
6172
|
function formatWeml(input) {
|
|
6146
|
-
const { html, entities: entities2 } = protectEntities(input);
|
|
6173
|
+
const { html, entities: entities2, marker } = protectEntities(input);
|
|
6147
6174
|
const doc = parse2(normalizeVoidTagSyntax(html));
|
|
6175
|
+
removeEmptyWrappers(doc);
|
|
6176
|
+
const title = doc.querySelector("head title");
|
|
6177
|
+
if (title) processInlineContent(title, true);
|
|
6148
6178
|
const body = doc.querySelector("body");
|
|
6149
6179
|
if (body) processBlockElement(body);
|
|
6150
|
-
return restoreEntities(serializeDocument(doc), entities2);
|
|
6180
|
+
return restoreEntities(serializeDocument(doc, entities2, marker), entities2, marker);
|
|
6151
6181
|
}
|
|
6152
6182
|
function protectEntities(input) {
|
|
6183
|
+
let markerLength = 1;
|
|
6184
|
+
let marker = PH_OPEN.repeat(markerLength) + PH_CLOSE;
|
|
6185
|
+
while (input.includes(marker)) {
|
|
6186
|
+
markerLength += 1;
|
|
6187
|
+
marker = PH_OPEN.repeat(markerLength) + PH_CLOSE;
|
|
6188
|
+
}
|
|
6153
6189
|
const entities2 = [];
|
|
6154
6190
|
const html = input.replace(ENTITY_RE2, (match) => {
|
|
6155
6191
|
const index = entities2.length;
|
|
6156
6192
|
entities2.push(match);
|
|
6157
|
-
return `${
|
|
6193
|
+
return `${marker}${index}${marker}`;
|
|
6158
6194
|
});
|
|
6159
|
-
return { html, entities: entities2 };
|
|
6160
|
-
}
|
|
6161
|
-
function restoreEntities(text, entities2) {
|
|
6162
|
-
|
|
6195
|
+
return { html, entities: entities2, marker };
|
|
6196
|
+
}
|
|
6197
|
+
function restoreEntities(text, entities2, marker) {
|
|
6198
|
+
const result = [];
|
|
6199
|
+
let position = 0;
|
|
6200
|
+
while (position < text.length) {
|
|
6201
|
+
const open = text.indexOf(marker, position);
|
|
6202
|
+
if (open < 0) {
|
|
6203
|
+
result.push(text.slice(position));
|
|
6204
|
+
break;
|
|
6205
|
+
}
|
|
6206
|
+
result.push(text.slice(position, open));
|
|
6207
|
+
const indexStart = open + marker.length;
|
|
6208
|
+
const close = text.indexOf(marker, indexStart);
|
|
6209
|
+
const indexText = close >= 0 ? text.slice(indexStart, close) : "";
|
|
6210
|
+
const entityIndex = Number(indexText);
|
|
6211
|
+
if (close < 0 || !/^[0-9]+$/.test(indexText) || !Number.isSafeInteger(entityIndex) || entityIndex >= entities2.length) {
|
|
6212
|
+
throw new Error("Invalid internal entity placeholder.");
|
|
6213
|
+
}
|
|
6214
|
+
result.push(entities2[entityIndex]);
|
|
6215
|
+
position = close + marker.length;
|
|
6216
|
+
}
|
|
6217
|
+
return result.join("");
|
|
6163
6218
|
}
|
|
6164
6219
|
function normalizeVoidTagSyntax(input) {
|
|
6165
|
-
|
|
6220
|
+
function slashBelongsToUnquotedValue(attrs) {
|
|
6221
|
+
let index2 = 0;
|
|
6222
|
+
const whitespace = /* @__PURE__ */ new Set([" ", " ", "\n", "\f", "\r", "\v"]);
|
|
6223
|
+
while (index2 < attrs.length) {
|
|
6224
|
+
while (index2 < attrs.length && whitespace.has(attrs[index2])) index2 += 1;
|
|
6225
|
+
if (index2 >= attrs.length || attrs[index2] === "/") return false;
|
|
6226
|
+
while (index2 < attrs.length && !whitespace.has(attrs[index2]) && !["=", "/"].includes(attrs[index2])) index2 += 1;
|
|
6227
|
+
while (index2 < attrs.length && whitespace.has(attrs[index2])) index2 += 1;
|
|
6228
|
+
if (index2 >= attrs.length || attrs[index2] !== "=") continue;
|
|
6229
|
+
index2 += 1;
|
|
6230
|
+
while (index2 < attrs.length && whitespace.has(attrs[index2])) index2 += 1;
|
|
6231
|
+
if (index2 >= attrs.length) return false;
|
|
6232
|
+
if (attrs[index2] === '"' || attrs[index2] === "'") {
|
|
6233
|
+
const quote = attrs[index2];
|
|
6234
|
+
index2 += 1;
|
|
6235
|
+
while (index2 < attrs.length && attrs[index2] !== quote) index2 += 1;
|
|
6236
|
+
if (index2 < attrs.length) index2 += 1;
|
|
6237
|
+
continue;
|
|
6238
|
+
}
|
|
6239
|
+
const valueStart = index2;
|
|
6240
|
+
while (index2 < attrs.length && !whitespace.has(attrs[index2])) index2 += 1;
|
|
6241
|
+
if (index2 === attrs.length) {
|
|
6242
|
+
return valueStart < attrs.length && attrs.endsWith("/");
|
|
6243
|
+
}
|
|
6244
|
+
}
|
|
6245
|
+
return false;
|
|
6246
|
+
}
|
|
6247
|
+
const result = [];
|
|
6248
|
+
let index = 0;
|
|
6249
|
+
while (index < input.length) {
|
|
6250
|
+
if (input[index] !== "<") {
|
|
6251
|
+
result.push(input[index++]);
|
|
6252
|
+
continue;
|
|
6253
|
+
}
|
|
6254
|
+
const start = index;
|
|
6255
|
+
if (input.startsWith("<!--", index) || input.startsWith("<?", index)) {
|
|
6256
|
+
const delimiter = input.startsWith("<!--", index) ? "-->" : "?>";
|
|
6257
|
+
let end2 = input.indexOf(delimiter, index + 2);
|
|
6258
|
+
end2 = end2 < 0 ? input.length : end2 + delimiter.length;
|
|
6259
|
+
result.push(input.slice(start, end2));
|
|
6260
|
+
index = end2;
|
|
6261
|
+
continue;
|
|
6262
|
+
}
|
|
6263
|
+
const { end } = findTagEnd(input, index + 1);
|
|
6264
|
+
if (end < 0) {
|
|
6265
|
+
result.push(input.slice(index));
|
|
6266
|
+
break;
|
|
6267
|
+
}
|
|
6268
|
+
let cursor = index + 1;
|
|
6269
|
+
if (input[cursor] === "!") {
|
|
6270
|
+
result.push(input.slice(start, end + 1));
|
|
6271
|
+
index = end + 1;
|
|
6272
|
+
continue;
|
|
6273
|
+
}
|
|
6274
|
+
const closing = input[cursor] === "/";
|
|
6275
|
+
if (closing) cursor++;
|
|
6276
|
+
if (cursor >= end || !isNameStart(input[cursor])) {
|
|
6277
|
+
result.push(input[index++]);
|
|
6278
|
+
continue;
|
|
6279
|
+
}
|
|
6280
|
+
const nameStart = cursor++;
|
|
6281
|
+
while (cursor < end && isNameChar(input[cursor])) cursor++;
|
|
6282
|
+
const name = input.slice(nameStart, cursor);
|
|
6283
|
+
const attributes = [];
|
|
6284
|
+
let quote = null;
|
|
6285
|
+
let inSpace = false;
|
|
6286
|
+
for (let offset = cursor; offset < end; offset++) {
|
|
6287
|
+
const character = input[offset];
|
|
6288
|
+
if (quote !== null) {
|
|
6289
|
+
attributes.push(character);
|
|
6290
|
+
if (character === quote) quote = null;
|
|
6291
|
+
continue;
|
|
6292
|
+
}
|
|
6293
|
+
if (isSourceSpace(character)) {
|
|
6294
|
+
if (!inSpace) attributes.push(" ");
|
|
6295
|
+
inSpace = true;
|
|
6296
|
+
} else {
|
|
6297
|
+
inSpace = false;
|
|
6298
|
+
attributes.push(character);
|
|
6299
|
+
if (character === '"' || character === "'") quote = character;
|
|
6300
|
+
}
|
|
6301
|
+
}
|
|
6302
|
+
let attrs = attributes.join("").replace(/ +$/, "");
|
|
6303
|
+
if (!closing && VOID_HTML_ELEMENTS.has(name.toLowerCase())) {
|
|
6304
|
+
if (attrs.endsWith("/") && !slashBelongsToUnquotedValue(attrs)) {
|
|
6305
|
+
attrs = attrs.slice(0, -1).replace(/ +$/, "");
|
|
6306
|
+
}
|
|
6307
|
+
result.push(`<${name.toLowerCase()}${attrs} />`);
|
|
6308
|
+
} else {
|
|
6309
|
+
result.push(input.slice(start, cursor), attrs, ">");
|
|
6310
|
+
}
|
|
6311
|
+
index = end + 1;
|
|
6312
|
+
}
|
|
6313
|
+
return result.join("");
|
|
6166
6314
|
}
|
|
6167
|
-
function
|
|
6315
|
+
function removeEmptyWrappers(node) {
|
|
6316
|
+
for (const child of [...node.childNodes]) {
|
|
6317
|
+
if (child.nodeType === 8) {
|
|
6318
|
+
node.removeChild(child);
|
|
6319
|
+
continue;
|
|
6320
|
+
}
|
|
6321
|
+
if (child.nodeType !== 1) continue;
|
|
6322
|
+
removeEmptyWrappers(child);
|
|
6323
|
+
const hasId = Object.keys(child.rawAttributes).some((name) => name.toLowerCase() === "id");
|
|
6324
|
+
if (EMPTY_TEXT_WRAPPERS.has(child.rawTagName.toLowerCase()) && !hasId && child.childNodes.every((item) => item.nodeType === 3 && isWhitespaceOnly(item.rawText))) {
|
|
6325
|
+
const replacement = new TextNode(child.childNodes.some((item) => item.rawText.length > 0) ? " " : "", node);
|
|
6326
|
+
node.exchangeChild(child, replacement);
|
|
6327
|
+
}
|
|
6328
|
+
}
|
|
6329
|
+
let previous = null;
|
|
6168
6330
|
for (const child of [...node.childNodes]) {
|
|
6169
|
-
if (child.nodeType === 3
|
|
6331
|
+
if (child.nodeType === 3) {
|
|
6332
|
+
if (previous !== null) {
|
|
6333
|
+
previous.rawText += child.rawText;
|
|
6334
|
+
node.removeChild(child);
|
|
6335
|
+
} else previous = child;
|
|
6336
|
+
} else previous = null;
|
|
6170
6337
|
}
|
|
6338
|
+
}
|
|
6339
|
+
function processBlockElement(node) {
|
|
6340
|
+
node.childNodes = node.childNodes.filter((child) => {
|
|
6341
|
+
if (child.nodeType !== 3) return true;
|
|
6342
|
+
const normalized = trimWhitespace(child.rawText);
|
|
6343
|
+
if (normalized) {
|
|
6344
|
+
child.rawText = normalized;
|
|
6345
|
+
return true;
|
|
6346
|
+
}
|
|
6347
|
+
child.parentNode = null;
|
|
6348
|
+
return false;
|
|
6349
|
+
});
|
|
6171
6350
|
for (const child of [...node.childNodes]) {
|
|
6172
6351
|
if (child.nodeType !== 1) continue;
|
|
6173
6352
|
const name = child.rawTagName.toLowerCase();
|
|
6174
6353
|
if (INLINE_CONTAINERS.has(name)) processInlineContainer(child);
|
|
6175
6354
|
else if (BLOCK_ELEMENTS.has(name)) processBlockElement(child);
|
|
6176
|
-
else if (
|
|
6355
|
+
else if (isInlineTextElement(child)) processInlineContent(child, true);
|
|
6177
6356
|
}
|
|
6178
6357
|
}
|
|
6179
6358
|
function processInlineContainer(node) {
|
|
@@ -6184,7 +6363,7 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6184
6363
|
for (const child of [...node.childNodes]) {
|
|
6185
6364
|
if (child.nodeType !== 1) continue;
|
|
6186
6365
|
const name = child.rawTagName.toLowerCase();
|
|
6187
|
-
if (
|
|
6366
|
+
if (isInlineTextElement(child)) {
|
|
6188
6367
|
if (hasDirectSentChildren(child)) processSentContainer(child);
|
|
6189
6368
|
else processInlineContent(child, false);
|
|
6190
6369
|
} else if (BLOCK_ELEMENTS.has(name)) {
|
|
@@ -6194,19 +6373,19 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6194
6373
|
}
|
|
6195
6374
|
}
|
|
6196
6375
|
for (const child of [...node.childNodes]) {
|
|
6197
|
-
if (child.nodeType === 1 &&
|
|
6376
|
+
if (child.nodeType === 1 && isInlineTextElement(child)) {
|
|
6198
6377
|
bleedEdgeSpaces(child);
|
|
6199
6378
|
}
|
|
6200
6379
|
}
|
|
6201
6380
|
for (const child of [...node.childNodes]) {
|
|
6202
|
-
if (child.nodeType === 3) child.rawText = child.rawText
|
|
6381
|
+
if (child.nodeType === 3) child.rawText = collapseWhitespace(child.rawText);
|
|
6203
6382
|
}
|
|
6204
6383
|
for (const child of [...node.childNodes]) {
|
|
6205
6384
|
if (child.nodeType === 1 && child.rawTagName.toLowerCase() === "br") {
|
|
6206
6385
|
const prev = child.previousSibling;
|
|
6207
|
-
if (prev && prev.nodeType === 3) prev.rawText = prev.rawText
|
|
6386
|
+
if (prev && prev.nodeType === 3) prev.rawText = trimEndWhitespace(prev.rawText);
|
|
6208
6387
|
const next = child.nextSibling;
|
|
6209
|
-
if (next && next.nodeType === 3) next.rawText = next.rawText
|
|
6388
|
+
if (next && next.nodeType === 3) next.rawText = trimStartWhitespace(next.rawText);
|
|
6210
6389
|
}
|
|
6211
6390
|
}
|
|
6212
6391
|
trimContainerEdges(node);
|
|
@@ -6220,17 +6399,17 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6220
6399
|
const first = children[0];
|
|
6221
6400
|
const last = children[children.length - 1];
|
|
6222
6401
|
if (children.length === 1) {
|
|
6223
|
-
if (first.nodeType === 3) first.rawText = first.rawText
|
|
6402
|
+
if (first.nodeType === 3) first.rawText = trimWhitespace(first.rawText);
|
|
6224
6403
|
} else {
|
|
6225
|
-
if (first.nodeType === 3) first.rawText = first.rawText
|
|
6226
|
-
if (last.nodeType === 3) last.rawText = last.rawText
|
|
6404
|
+
if (first.nodeType === 3) first.rawText = trimStartWhitespace(first.rawText);
|
|
6405
|
+
if (last.nodeType === 3) last.rawText = trimEndWhitespace(last.rawText);
|
|
6227
6406
|
}
|
|
6228
6407
|
}
|
|
6229
6408
|
function processInlineContent(node, trimEdges) {
|
|
6230
6409
|
for (const child of [...node.childNodes]) {
|
|
6231
6410
|
if (child.nodeType !== 1) continue;
|
|
6232
6411
|
const name = child.rawTagName.toLowerCase();
|
|
6233
|
-
if (
|
|
6412
|
+
if (isInlineTextElement(child)) {
|
|
6234
6413
|
if (hasDirectSentChildren(child)) processSentContainer(child);
|
|
6235
6414
|
else processInlineContent(child, false);
|
|
6236
6415
|
} else if (BLOCK_ELEMENTS.has(name)) {
|
|
@@ -6240,19 +6419,19 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6240
6419
|
}
|
|
6241
6420
|
}
|
|
6242
6421
|
for (const child of [...node.childNodes]) {
|
|
6243
|
-
if (child.nodeType === 1 &&
|
|
6422
|
+
if (child.nodeType === 1 && isInlineTextElement(child)) {
|
|
6244
6423
|
bleedEdgeSpaces(child);
|
|
6245
6424
|
}
|
|
6246
6425
|
}
|
|
6247
6426
|
for (const child of [...node.childNodes]) {
|
|
6248
|
-
if (child.nodeType === 3) child.rawText = child.rawText
|
|
6427
|
+
if (child.nodeType === 3) child.rawText = collapseWhitespace(child.rawText);
|
|
6249
6428
|
}
|
|
6250
6429
|
for (const child of [...node.childNodes]) {
|
|
6251
6430
|
if (child.nodeType === 1 && child.rawTagName.toLowerCase() === "br") {
|
|
6252
6431
|
const prev = child.previousSibling;
|
|
6253
|
-
if (prev && prev.nodeType === 3) prev.rawText = prev.rawText
|
|
6432
|
+
if (prev && prev.nodeType === 3) prev.rawText = trimEndWhitespace(prev.rawText);
|
|
6254
6433
|
const next = child.nextSibling;
|
|
6255
|
-
if (next && next.nodeType === 3) next.rawText = next.rawText
|
|
6434
|
+
if (next && next.nodeType === 3) next.rawText = trimStartWhitespace(next.rawText);
|
|
6256
6435
|
}
|
|
6257
6436
|
}
|
|
6258
6437
|
if (trimEdges) trimEdgeTextNodes(node);
|
|
@@ -6290,7 +6469,7 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6290
6469
|
const first = getFirstTextNode(node);
|
|
6291
6470
|
if (!first) return "";
|
|
6292
6471
|
const raw = first.rawText;
|
|
6293
|
-
const trimmed = raw
|
|
6472
|
+
const trimmed = trimStartWhitespace(raw);
|
|
6294
6473
|
if (trimmed === raw) return "";
|
|
6295
6474
|
first.rawText = trimmed;
|
|
6296
6475
|
return " ";
|
|
@@ -6299,7 +6478,7 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6299
6478
|
const last = getLastTextNode(node);
|
|
6300
6479
|
if (!last) return "";
|
|
6301
6480
|
const raw = last.rawText;
|
|
6302
|
-
const trimmed = raw
|
|
6481
|
+
const trimmed = trimEndWhitespace(raw);
|
|
6303
6482
|
if (trimmed === raw) return "";
|
|
6304
6483
|
last.rawText = trimmed;
|
|
6305
6484
|
return " ";
|
|
@@ -6336,10 +6515,10 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6336
6515
|
const first = children[0];
|
|
6337
6516
|
const last = children[children.length - 1];
|
|
6338
6517
|
if (first === last) {
|
|
6339
|
-
if (first.nodeType === 3) first.rawText = first.rawText
|
|
6518
|
+
if (first.nodeType === 3) first.rawText = trimWhitespace(first.rawText);
|
|
6340
6519
|
} else {
|
|
6341
|
-
if (first.nodeType === 3) first.rawText = first.rawText
|
|
6342
|
-
if (last.nodeType === 3) last.rawText = last.rawText
|
|
6520
|
+
if (first.nodeType === 3) first.rawText = trimStartWhitespace(first.rawText);
|
|
6521
|
+
if (last.nodeType === 3) last.rawText = trimEndWhitespace(last.rawText);
|
|
6343
6522
|
}
|
|
6344
6523
|
}
|
|
6345
6524
|
function hasDirectSentChildren(node) {
|
|
@@ -6347,17 +6526,22 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6347
6526
|
(child) => child.nodeType === 1 && child.rawTagName.toLowerCase() === "w-sent"
|
|
6348
6527
|
);
|
|
6349
6528
|
}
|
|
6350
|
-
function
|
|
6529
|
+
function isInlineTextElement(node) {
|
|
6530
|
+
if (node.nodeType !== 1) return false;
|
|
6531
|
+
const name = node.rawTagName.toLowerCase();
|
|
6532
|
+
return INLINE_ELEMENTS.has(name) || !BLOCK_ELEMENTS.has(name) && !INLINE_CONTAINERS.has(name) && !VOID_HTML_ELEMENTS.has(name);
|
|
6533
|
+
}
|
|
6534
|
+
function serializeDocument(doc, entities2, marker) {
|
|
6351
6535
|
const parts = ["<!DOCTYPE html>\n"];
|
|
6352
6536
|
const htmlNode = doc.querySelector("html");
|
|
6353
|
-
parts.push(`<html${serializeAttrs(htmlNode ? htmlNode.
|
|
6537
|
+
parts.push(`<html${serializeAttrs(htmlNode ? htmlNode.rawAttrs : "", entities2, marker)}>
|
|
6354
6538
|
|
|
6355
6539
|
`);
|
|
6356
6540
|
const head = doc.querySelector("head");
|
|
6357
6541
|
parts.push("<head>\n");
|
|
6358
6542
|
if (head) {
|
|
6359
6543
|
for (const child of head.childNodes) {
|
|
6360
|
-
if (child.nodeType === 1) parts.push(serializeNode(child), "\n");
|
|
6544
|
+
if (child.nodeType === 1) parts.push(serializeNode(child, entities2, marker), "\n");
|
|
6361
6545
|
}
|
|
6362
6546
|
}
|
|
6363
6547
|
parts.push("</head>\n\n");
|
|
@@ -6365,28 +6549,81 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6365
6549
|
parts.push("<body>\n");
|
|
6366
6550
|
if (body) {
|
|
6367
6551
|
for (const child of body.childNodes) {
|
|
6368
|
-
if (child.nodeType === 1) parts.push(serializeNode(child), "\n");
|
|
6552
|
+
if (child.nodeType === 1) parts.push(serializeNode(child, entities2, marker), "\n");
|
|
6369
6553
|
}
|
|
6370
6554
|
}
|
|
6371
6555
|
parts.push("</body>\n</html>");
|
|
6372
6556
|
return parts.join("");
|
|
6373
6557
|
}
|
|
6374
|
-
function serializeNode(node) {
|
|
6558
|
+
function serializeNode(node, entities2, marker) {
|
|
6375
6559
|
if (node.nodeType === 3) return node.rawText;
|
|
6376
6560
|
if (node.nodeType === 8 || node.nodeType !== 1) return "";
|
|
6377
6561
|
const name = node.rawTagName.toLowerCase();
|
|
6378
|
-
const attrs = serializeAttrs(node.
|
|
6562
|
+
const attrs = serializeAttrs(node.rawAttrs, entities2, marker);
|
|
6379
6563
|
if (VOID_HTML_ELEMENTS.has(name)) return `<${name}${attrs} />`;
|
|
6380
6564
|
const isBlock = BLOCK_ELEMENTS.has(name);
|
|
6381
6565
|
const inner = [];
|
|
6382
6566
|
for (const child of node.childNodes) {
|
|
6383
|
-
if (isBlock && child.nodeType === 3 && child.rawText
|
|
6384
|
-
inner.push(serializeNode(child));
|
|
6567
|
+
if (isBlock && child.nodeType === 3 && isWhitespaceOnly(child.rawText)) continue;
|
|
6568
|
+
inner.push(serializeNode(child, entities2, marker));
|
|
6385
6569
|
}
|
|
6386
6570
|
return `<${name}${attrs}>${inner.join("")}</${name}>`;
|
|
6387
6571
|
}
|
|
6388
|
-
function serializeAttrs(
|
|
6389
|
-
|
|
6572
|
+
function serializeAttrs(rawAttrs, entities2, marker) {
|
|
6573
|
+
const canonical = /* @__PURE__ */ new Map();
|
|
6574
|
+
let index = 0;
|
|
6575
|
+
while (index < rawAttrs.length) {
|
|
6576
|
+
while (index < rawAttrs.length && isNormalizableWhitespace(rawAttrs[index])) index++;
|
|
6577
|
+
if (index >= rawAttrs.length || rawAttrs[index] === "/") break;
|
|
6578
|
+
const nameStart = index;
|
|
6579
|
+
while (index < rawAttrs.length && !isNormalizableWhitespace(rawAttrs[index]) && !"=/>".includes(rawAttrs[index])) index++;
|
|
6580
|
+
if (index === nameStart) {
|
|
6581
|
+
index++;
|
|
6582
|
+
continue;
|
|
6583
|
+
}
|
|
6584
|
+
const name = rawAttrs.slice(nameStart, index).toLowerCase();
|
|
6585
|
+
while (index < rawAttrs.length && isNormalizableWhitespace(rawAttrs[index])) index++;
|
|
6586
|
+
let value = "";
|
|
6587
|
+
if (rawAttrs[index] === "=") {
|
|
6588
|
+
index++;
|
|
6589
|
+
while (index < rawAttrs.length && isNormalizableWhitespace(rawAttrs[index])) index++;
|
|
6590
|
+
if (rawAttrs[index] === '"' || rawAttrs[index] === "'") {
|
|
6591
|
+
const quote = rawAttrs[index++];
|
|
6592
|
+
const valueStart = index;
|
|
6593
|
+
while (index < rawAttrs.length && rawAttrs[index] !== quote) index++;
|
|
6594
|
+
value = rawAttrs.slice(valueStart, index);
|
|
6595
|
+
if (index < rawAttrs.length) index++;
|
|
6596
|
+
} else {
|
|
6597
|
+
const valueStart = index;
|
|
6598
|
+
while (index < rawAttrs.length && !isNormalizableWhitespace(rawAttrs[index])) index++;
|
|
6599
|
+
value = rawAttrs.slice(valueStart, index);
|
|
6600
|
+
}
|
|
6601
|
+
}
|
|
6602
|
+
canonical.set(
|
|
6603
|
+
name,
|
|
6604
|
+
SPACE_SEPARATED_ATTRIBUTES.has(name) ? normalizeTokenList(value, entities2, marker) : trimWhitespace(value)
|
|
6605
|
+
);
|
|
6606
|
+
}
|
|
6607
|
+
return [...canonical.entries()].sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([name, value]) => ` ${name}="${encodeAttr(String(value))}"`).join("");
|
|
6608
|
+
}
|
|
6609
|
+
function normalizeTokenList(value, entities2, marker) {
|
|
6610
|
+
const normalized = trimWhitespace(value);
|
|
6611
|
+
if (!normalized) return normalized;
|
|
6612
|
+
return normalized.split(" ").sort((left, right) => compareUnicodeScalars(
|
|
6613
|
+
restoreEntities(left, entities2, marker),
|
|
6614
|
+
restoreEntities(right, entities2, marker)
|
|
6615
|
+
)).join(" ");
|
|
6616
|
+
}
|
|
6617
|
+
function compareUnicodeScalars(left, right) {
|
|
6618
|
+
const leftScalars = Array.from(left, (character) => character.codePointAt(0));
|
|
6619
|
+
const rightScalars = Array.from(right, (character) => character.codePointAt(0));
|
|
6620
|
+
const limit = Math.min(leftScalars.length, rightScalars.length);
|
|
6621
|
+
for (let index = 0; index < limit; index++) {
|
|
6622
|
+
if (leftScalars[index] !== rightScalars[index]) {
|
|
6623
|
+
return leftScalars[index] - rightScalars[index];
|
|
6624
|
+
}
|
|
6625
|
+
}
|
|
6626
|
+
return leftScalars.length - rightScalars.length;
|
|
6390
6627
|
}
|
|
6391
6628
|
function encodeAttr(value) {
|
|
6392
6629
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
@@ -6424,6 +6661,7 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6424
6661
|
}
|
|
6425
6662
|
};
|
|
6426
6663
|
function wemlContentNormalize2(input, isWemlValid = false) {
|
|
6664
|
+
if (input.startsWith("\uFEFF")) input = input.slice(1);
|
|
6427
6665
|
const inputText = withoutWhiteSpace(analyze(input, !isWemlValid).text);
|
|
6428
6666
|
const result = formatWeml(input);
|
|
6429
6667
|
const outputText = withoutWhiteSpace(analyze(result, true).text);
|
|
@@ -6438,6 +6676,9 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6438
6676
|
if (source[index2] === "\n") lineStarts.push(index2 + 1);
|
|
6439
6677
|
}
|
|
6440
6678
|
const stack = [];
|
|
6679
|
+
const rootTagCounts = /* @__PURE__ */ new Map([["html", 0], ["head", 0], ["body", 0]]);
|
|
6680
|
+
let seenHead = false;
|
|
6681
|
+
let seenBody = false;
|
|
6441
6682
|
const textParts = [];
|
|
6442
6683
|
let textStart = 0;
|
|
6443
6684
|
let index = 0;
|
|
@@ -6521,6 +6762,26 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6521
6762
|
if (expected !== name) fail("MISMATCHED_CLOSING_TAG", index, expected, name);
|
|
6522
6763
|
stack.pop();
|
|
6523
6764
|
} else {
|
|
6765
|
+
if (rootTagCounts.has(name)) {
|
|
6766
|
+
if (rootTagCounts.get(name) > 0) {
|
|
6767
|
+
fail("DUPLICATE_ROOT_TAG", index, null, name);
|
|
6768
|
+
}
|
|
6769
|
+
const parent = stack.length > 0 ? stack.at(-1).name : null;
|
|
6770
|
+
if (name === "html") {
|
|
6771
|
+
if (parent !== null) fail("INVALID_ROOT_TAG_PARENT", index, null, name);
|
|
6772
|
+
} else if (parent !== "html") {
|
|
6773
|
+
fail("INVALID_ROOT_TAG_PARENT", index, "html", name);
|
|
6774
|
+
}
|
|
6775
|
+
if (name === "body" && !seenHead) {
|
|
6776
|
+
fail("BODY_BEFORE_HEAD", index, "head", "body");
|
|
6777
|
+
}
|
|
6778
|
+
if (name === "head" && seenBody) {
|
|
6779
|
+
fail("HEAD_AFTER_BODY", index, "body", "head");
|
|
6780
|
+
}
|
|
6781
|
+
rootTagCounts.set(name, rootTagCounts.get(name) + 1);
|
|
6782
|
+
seenHead || (seenHead = name === "head");
|
|
6783
|
+
seenBody || (seenBody = name === "body");
|
|
6784
|
+
}
|
|
6524
6785
|
let last = found.end - 1;
|
|
6525
6786
|
while (last >= cursor && isSourceSpace(source[last])) last--;
|
|
6526
6787
|
const selfClosing = last >= cursor && source[last] === "/";
|
|
@@ -6542,6 +6803,11 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6542
6803
|
null
|
|
6543
6804
|
);
|
|
6544
6805
|
}
|
|
6806
|
+
if (validateStructure) {
|
|
6807
|
+
for (const name of ["html", "head", "body"]) {
|
|
6808
|
+
if (rootTagCounts.get(name) === 0) fail("MISSING_ROOT_TAG", 0, name, null);
|
|
6809
|
+
}
|
|
6810
|
+
}
|
|
6545
6811
|
return { text: textParts.join("") };
|
|
6546
6812
|
}
|
|
6547
6813
|
function findTagEnd(source, start) {
|
|
@@ -6565,11 +6831,40 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6565
6831
|
return isNameStart(character) || character >= "0" && character <= "9" || character === "-" || character === "_" || character === ":" || character === ".";
|
|
6566
6832
|
}
|
|
6567
6833
|
function isSourceSpace(character) {
|
|
6568
|
-
return character
|
|
6834
|
+
return isNormalizableWhitespace(character);
|
|
6569
6835
|
}
|
|
6570
6836
|
function withoutWhiteSpace(text) {
|
|
6571
6837
|
return Array.from(text, (character) => WHITE_SPACE.has(character.codePointAt(0)) ? "" : character).join("");
|
|
6572
6838
|
}
|
|
6839
|
+
function isNormalizableWhitespace(character) {
|
|
6840
|
+
return character !== void 0 && WHITE_SPACE.has(character.codePointAt(0));
|
|
6841
|
+
}
|
|
6842
|
+
function collapseWhitespace(text) {
|
|
6843
|
+
const result = [];
|
|
6844
|
+
let inWhitespace = false;
|
|
6845
|
+
for (const character of text) {
|
|
6846
|
+
if (isNormalizableWhitespace(character)) {
|
|
6847
|
+
if (!inWhitespace) result.push(" ");
|
|
6848
|
+
inWhitespace = true;
|
|
6849
|
+
} else {
|
|
6850
|
+
result.push(character);
|
|
6851
|
+
inWhitespace = false;
|
|
6852
|
+
}
|
|
6853
|
+
}
|
|
6854
|
+
return result.join("");
|
|
6855
|
+
}
|
|
6856
|
+
function trimStartWhitespace(text) {
|
|
6857
|
+
return collapseWhitespace(text).replace(/^ +/, "");
|
|
6858
|
+
}
|
|
6859
|
+
function trimEndWhitespace(text) {
|
|
6860
|
+
return collapseWhitespace(text).replace(/ +$/, "");
|
|
6861
|
+
}
|
|
6862
|
+
function trimWhitespace(text) {
|
|
6863
|
+
return collapseWhitespace(text).replace(/^ +| +$/g, "");
|
|
6864
|
+
}
|
|
6865
|
+
function isWhitespaceOnly(text) {
|
|
6866
|
+
return Array.from(text).every(isNormalizableWhitespace);
|
|
6867
|
+
}
|
|
6573
6868
|
function sha256(text) {
|
|
6574
6869
|
const crypto = require("crypto");
|
|
6575
6870
|
return crypto.createHash("sha256").update(text, "utf8").digest("hex");
|
|
@@ -6589,6 +6884,16 @@ var require_wemlContentNormalizeV2 = __commonJS({
|
|
|
6589
6884
|
detail = `unexpected closing tag </${actualTag}>.`;
|
|
6590
6885
|
} else if (code === "UNCLOSED_TAG") {
|
|
6591
6886
|
detail = `tag <${expectedTag}> is not closed.`;
|
|
6887
|
+
} else if (code === "DUPLICATE_ROOT_TAG") {
|
|
6888
|
+
detail = `document contains more than one <${actualTag}> tag.`;
|
|
6889
|
+
} else if (code === "INVALID_ROOT_TAG_PARENT") {
|
|
6890
|
+
detail = expectedTag ? `tag <${actualTag}> must be a direct child of <${expectedTag}>.` : `root tag <${actualTag}> must not be nested.`;
|
|
6891
|
+
} else if (code === "BODY_BEFORE_HEAD") {
|
|
6892
|
+
detail = "tag <body> appears before <head>.";
|
|
6893
|
+
} else if (code === "HEAD_AFTER_BODY") {
|
|
6894
|
+
detail = "tag <head> appears after <body>.";
|
|
6895
|
+
} else if (code === "MISSING_ROOT_TAG") {
|
|
6896
|
+
detail = `required root tag <${expectedTag}> is missing.`;
|
|
6592
6897
|
} else if (code === "UNTERMINATED_COMMENT") {
|
|
6593
6898
|
detail = "comment is not terminated.";
|
|
6594
6899
|
} else if (code === "UNTERMINATED_DECLARATION") {
|
|
@@ -29261,6 +29566,13 @@ var TAGS = {
|
|
|
29261
29566
|
"default": "paragraph",
|
|
29262
29567
|
"description": "Type of the paragraph. See corresponding page for values",
|
|
29263
29568
|
"enumRef": "paragraph-type"
|
|
29569
|
+
},
|
|
29570
|
+
{
|
|
29571
|
+
"name": "align",
|
|
29572
|
+
"required": false,
|
|
29573
|
+
"default": "`left` for LTR, `right` for RTL",
|
|
29574
|
+
"description": "Horizontal alignment. See corresponding page for allowed values",
|
|
29575
|
+
"enumRef": "horizontal-alignment"
|
|
29264
29576
|
}
|
|
29265
29577
|
],
|
|
29266
29578
|
"notes": "",
|
|
@@ -29273,6 +29585,24 @@ var TAGS = {
|
|
|
29273
29585
|
"notes": "Current line is broken and the next line is started. Next line has the same alignment\nas the current line, and the same indentation level as any line other than the first.",
|
|
29274
29586
|
"source": "inlines/br.md"
|
|
29275
29587
|
},
|
|
29588
|
+
"w-color": {
|
|
29589
|
+
"tag": "w-color",
|
|
29590
|
+
"description": "Represents an inline span with a foreground color, a background color, or both.",
|
|
29591
|
+
"attributes": [
|
|
29592
|
+
{
|
|
29593
|
+
"name": "background",
|
|
29594
|
+
"required": false,
|
|
29595
|
+
"description": "Background color. See Colors."
|
|
29596
|
+
},
|
|
29597
|
+
{
|
|
29598
|
+
"name": "foreground",
|
|
29599
|
+
"required": false,
|
|
29600
|
+
"description": "Foreground color. See Colors."
|
|
29601
|
+
}
|
|
29602
|
+
],
|
|
29603
|
+
"notes": "Any inline elements.",
|
|
29604
|
+
"source": "inlines/w-color.md"
|
|
29605
|
+
},
|
|
29276
29606
|
"w-entity": {
|
|
29277
29607
|
"tag": "w-entity",
|
|
29278
29608
|
"description": "An entity is a reference to a person, place, or thing. Entities are used to",
|
|
@@ -29405,6 +29735,16 @@ var TAGS = {
|
|
|
29405
29735
|
"name": "override-chapter-number",
|
|
29406
29736
|
"required": false,
|
|
29407
29737
|
"description": "Chapter number for manual set"
|
|
29738
|
+
},
|
|
29739
|
+
{
|
|
29740
|
+
"name": "background",
|
|
29741
|
+
"required": false,
|
|
29742
|
+
"description": "Background color. See Colors"
|
|
29743
|
+
},
|
|
29744
|
+
{
|
|
29745
|
+
"name": "foreground",
|
|
29746
|
+
"required": false,
|
|
29747
|
+
"description": "Foreground color. See Colors"
|
|
29408
29748
|
}
|
|
29409
29749
|
],
|
|
29410
29750
|
"notes": "Must contain a single text block element.",
|
|
@@ -29435,6 +29775,16 @@ var TAGS = {
|
|
|
29435
29775
|
"required": false,
|
|
29436
29776
|
"description": "Horizontal alignment. See corresponding page for allowed values. Defaults to `left` for left-to-right languages and `right` to right-to-left",
|
|
29437
29777
|
"enumRef": "horizontal-alignment"
|
|
29778
|
+
},
|
|
29779
|
+
{
|
|
29780
|
+
"name": "background",
|
|
29781
|
+
"required": false,
|
|
29782
|
+
"description": "Background color. See Colors"
|
|
29783
|
+
},
|
|
29784
|
+
{
|
|
29785
|
+
"name": "foreground",
|
|
29786
|
+
"required": false,
|
|
29787
|
+
"description": "Foreground color. See Colors"
|
|
29438
29788
|
}
|
|
29439
29789
|
],
|
|
29440
29790
|
"notes": "Must contain a single block element.",
|
|
@@ -29791,8 +30141,12 @@ var META_FIELDS = [
|
|
|
29791
30141
|
"description": "Publication description."
|
|
29792
30142
|
},
|
|
29793
30143
|
{
|
|
29794
|
-
"name": "
|
|
29795
|
-
"description": "
|
|
30144
|
+
"name": "purchase-link",
|
|
30145
|
+
"description": "Purchase link."
|
|
30146
|
+
},
|
|
30147
|
+
{
|
|
30148
|
+
"name": "version-id",
|
|
30149
|
+
"description": "Publication version GUID."
|
|
29796
30150
|
}
|
|
29797
30151
|
];
|
|
29798
30152
|
|
|
@@ -30049,7 +30403,7 @@ Unicode: \`U+${resolved.codePoint.toString(16).toUpperCase().padStart(4, "0")}\`
|
|
|
30049
30403
|
// src/schema/structureRules.ts
|
|
30050
30404
|
var CONTAINER_TAGS = ["w-para", "w-heading", "w-para-group", "w-toc"];
|
|
30051
30405
|
var BLOCK_TAGS = ["w-text-block", "figure", "w-list", "table", "hr"];
|
|
30052
|
-
var INLINE_TAGS = ["a", "br", "w-entity", "w-format", "w-lang", "w-non-egw", "w-note", "w-page", "w-sent"];
|
|
30406
|
+
var INLINE_TAGS = ["a", "br", "w-color", "w-entity", "w-format", "w-lang", "w-non-egw", "w-note", "w-page", "w-sent"];
|
|
30053
30407
|
var STRUCTURE_RULES = {
|
|
30054
30408
|
html: {
|
|
30055
30409
|
children: [
|
|
@@ -30196,6 +30550,13 @@ var STRUCTURE_RULES = {
|
|
|
30196
30550
|
allowText: true,
|
|
30197
30551
|
description: "With href: a link that may contain inline content. With id: a named anchor that must be empty. Exactly one of href/id is required, not both."
|
|
30198
30552
|
},
|
|
30553
|
+
"w-color": {
|
|
30554
|
+
children: [
|
|
30555
|
+
{ tags: [...INLINE_TAGS], min: 0, max: null, description: "inline elements" }
|
|
30556
|
+
],
|
|
30557
|
+
allowText: true,
|
|
30558
|
+
description: "May contain inline elements and text; requires a foreground or background color."
|
|
30559
|
+
},
|
|
30199
30560
|
"w-entity": {
|
|
30200
30561
|
children: [
|
|
30201
30562
|
{ tags: [...INLINE_TAGS], min: 0, max: null, description: "inline elements" }
|
|
@@ -30269,11 +30630,18 @@ var STRUCTURE_RULES = {
|
|
|
30269
30630
|
}
|
|
30270
30631
|
};
|
|
30271
30632
|
var ARABIC_OR_ROMAN = /^(?:\d+|[ivxlcdm]+)$/i;
|
|
30633
|
+
var COLOR_VALUE = /^#(?:[0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
|
|
30272
30634
|
var ATTRIBUTE_CONSTRAINTS = [
|
|
30273
30635
|
{ tag: "w-heading", attribute: "level", kind: "integer-range", min: 1, max: 6, message: "`level` must be an integer between 1 and 6." },
|
|
30274
30636
|
{ tag: "w-heading", attribute: "override-chapter-number", kind: "integer-min", min: 0, message: "`override-chapter-number` must be a non-negative integer." },
|
|
30637
|
+
{ tag: "w-heading", attribute: "background", kind: "pattern", pattern: COLOR_VALUE, allowEmpty: false, message: "`background` must be a color in #RGB, #RGBA, #RRGGBB or #RRGGBBAA format." },
|
|
30638
|
+
{ tag: "w-heading", attribute: "foreground", kind: "pattern", pattern: COLOR_VALUE, allowEmpty: false, message: "`foreground` must be a color in #RGB, #RGBA, #RRGGBB or #RRGGBBAA format." },
|
|
30275
30639
|
{ tag: "w-page", attribute: "number", kind: "pattern", pattern: ARABIC_OR_ROMAN, message: "`number` must be an arabic or roman number." },
|
|
30276
30640
|
{ tag: "w-para", attribute: "indent", kind: "integer-min", min: -4, message: "`indent` must be an integer >= -4." },
|
|
30641
|
+
{ tag: "w-para", attribute: "background", kind: "pattern", pattern: COLOR_VALUE, allowEmpty: false, message: "`background` must be a color in #RGB, #RGBA, #RRGGBB or #RRGGBBAA format." },
|
|
30642
|
+
{ tag: "w-para", attribute: "foreground", kind: "pattern", pattern: COLOR_VALUE, allowEmpty: false, message: "`foreground` must be a color in #RGB, #RGBA, #RRGGBB or #RRGGBBAA format." },
|
|
30643
|
+
{ tag: "w-color", attribute: "background", kind: "pattern", pattern: COLOR_VALUE, allowEmpty: false, message: "`background` must be a color in #RGB, #RGBA, #RRGGBB or #RRGGBBAA format." },
|
|
30644
|
+
{ tag: "w-color", attribute: "foreground", kind: "pattern", pattern: COLOR_VALUE, allowEmpty: false, message: "`foreground` must be a color in #RGB, #RGBA, #RRGGBB or #RRGGBBAA format." },
|
|
30277
30645
|
{ tag: "w-note-para", attribute: "indent", kind: "integer-min", min: 0, message: "`indent` must be an integer >= 0." },
|
|
30278
30646
|
{ tag: "td", attribute: "indent", kind: "integer-min", min: -4, message: "`indent` must be an integer >= -4." },
|
|
30279
30647
|
{ tag: "th", attribute: "indent", kind: "integer-min", min: -4, message: "`indent` must be an integer >= -4." },
|
|
@@ -30414,6 +30782,9 @@ function indent(text) {
|
|
|
30414
30782
|
function buildElement(tag, counter, depth) {
|
|
30415
30783
|
const schema = TAGS[tag];
|
|
30416
30784
|
let attrs = "";
|
|
30785
|
+
if (tag === "w-color") {
|
|
30786
|
+
attrs = ` foreground="${placeholder(counter)}"`;
|
|
30787
|
+
}
|
|
30417
30788
|
for (const attr of schema?.attributes ?? []) {
|
|
30418
30789
|
if (attr.required) {
|
|
30419
30790
|
attrs += ` ${attr.name}="${placeholder(counter)}"`;
|
|
@@ -30449,6 +30820,9 @@ function buildElementSnippet(tag) {
|
|
|
30449
30820
|
function buildOpeningTag(tag) {
|
|
30450
30821
|
const counter = { n: 1 };
|
|
30451
30822
|
let attrs = "";
|
|
30823
|
+
if (tag === "w-color") {
|
|
30824
|
+
attrs = ` foreground="${placeholder(counter)}"`;
|
|
30825
|
+
}
|
|
30452
30826
|
for (const attr of TAGS[tag]?.attributes ?? []) {
|
|
30453
30827
|
if (attr.required) {
|
|
30454
30828
|
attrs += ` ${attr.name}="${placeholder(counter)}"`;
|
|
@@ -30556,24 +30930,22 @@ function getCompletionContext(text, offset, nodeStart) {
|
|
|
30556
30930
|
switch (token) {
|
|
30557
30931
|
case TokenType.StartTagOpen:
|
|
30558
30932
|
if (scanner.getTokenEnd() === offset) {
|
|
30559
|
-
|
|
30560
|
-
return { kind: "tag", start: offset - 1, end, includesBracket: true };
|
|
30933
|
+
return { kind: "tag", start: offset - 1, end: offset, includesBracket: true };
|
|
30561
30934
|
}
|
|
30562
30935
|
break;
|
|
30563
30936
|
case TokenType.EndTagOpen:
|
|
30564
30937
|
if (scanner.getTokenEnd() === offset) {
|
|
30565
|
-
|
|
30566
|
-
return { kind: "end-tag", start: offset, end };
|
|
30938
|
+
return { kind: "end-tag", start: offset, end: offset };
|
|
30567
30939
|
}
|
|
30568
30940
|
break;
|
|
30569
30941
|
case TokenType.EndTag:
|
|
30570
30942
|
if (scanner.getTokenOffset() <= offset && offset <= scanner.getTokenEnd()) {
|
|
30571
|
-
return { kind: "end-tag", start: scanner.getTokenOffset(), end:
|
|
30943
|
+
return { kind: "end-tag", start: scanner.getTokenOffset(), end: offset };
|
|
30572
30944
|
}
|
|
30573
30945
|
break;
|
|
30574
30946
|
case TokenType.StartTag:
|
|
30575
30947
|
if (scanner.getTokenOffset() <= offset && offset <= scanner.getTokenEnd()) {
|
|
30576
|
-
return { kind: "tag", start: scanner.getTokenOffset(), end:
|
|
30948
|
+
return { kind: "tag", start: scanner.getTokenOffset(), end: offset, includesBracket: false };
|
|
30577
30949
|
}
|
|
30578
30950
|
currentTag = scanner.getTokenText();
|
|
30579
30951
|
break;
|
|
@@ -30611,8 +30983,7 @@ function getCompletionContext(text, offset, nodeStart) {
|
|
|
30611
30983
|
switch (scanner.getScannerState()) {
|
|
30612
30984
|
case ScannerState.AfterOpeningStartTag: {
|
|
30613
30985
|
const start = scanner.getTokenOffset();
|
|
30614
|
-
|
|
30615
|
-
return { kind: "tag", start, end, includesBracket: false };
|
|
30986
|
+
return { kind: "tag", start, end: offset, includesBracket: false };
|
|
30616
30987
|
}
|
|
30617
30988
|
case ScannerState.WithinTag:
|
|
30618
30989
|
case ScannerState.AfterAttributeName:
|
|
@@ -30652,6 +31023,7 @@ function dedupe(items) {
|
|
|
30652
31023
|
function hasValueSuggestions(tag, attribute, enumRef) {
|
|
30653
31024
|
if (enumRef && ENUMS[enumRef]) return true;
|
|
30654
31025
|
if (tag === "w-heading" && attribute === "level") return true;
|
|
31026
|
+
if (tag === "meta" && attribute === "name") return true;
|
|
30655
31027
|
if (tag === "meta" && attribute === "content") return true;
|
|
30656
31028
|
if (tag === "a" && attribute === "href") return true;
|
|
30657
31029
|
return false;
|
|
@@ -30821,6 +31193,18 @@ var WemlCompletionProvider = class {
|
|
|
30821
31193
|
});
|
|
30822
31194
|
}
|
|
30823
31195
|
}
|
|
31196
|
+
if (ctx.tag === "meta" && ctx.attribute === "name") {
|
|
31197
|
+
for (const field of META_FIELDS) {
|
|
31198
|
+
items.push({
|
|
31199
|
+
label: field.name,
|
|
31200
|
+
kind: this.m.languages.CompletionItemKind.Property,
|
|
31201
|
+
detail: "WEML metadata field",
|
|
31202
|
+
documentation: metaFieldMarkdown(field.name),
|
|
31203
|
+
insertText: wrap(field.name),
|
|
31204
|
+
range
|
|
31205
|
+
});
|
|
31206
|
+
}
|
|
31207
|
+
}
|
|
30824
31208
|
if (ctx.tag === "meta" && ctx.attribute === "content" && stripQuotes2(node.attributes?.["name"]) === "type") {
|
|
30825
31209
|
const codeEnum = ENUMS["publication-type"];
|
|
30826
31210
|
if (codeEnum) {
|
|
@@ -30978,6 +31362,9 @@ function validateWemlModel(m, model) {
|
|
|
30978
31362
|
push(href.valueRange, `Unrecognized href format "${href.value}". Expected formats like: ${types}.`, "warning");
|
|
30979
31363
|
}
|
|
30980
31364
|
}
|
|
31365
|
+
if (tag === "w-color" && !attrs.has("background") && !attrs.has("foreground")) {
|
|
31366
|
+
push(tagRange, '<w-color> must have either "background" or "foreground".', "error");
|
|
31367
|
+
}
|
|
30981
31368
|
if (tag === "div") {
|
|
30982
31369
|
const id = stripQuotes2(node.attributes?.["id"]);
|
|
30983
31370
|
const range = attrs.get("id")?.valueRange ?? tagRange;
|
|
@@ -30991,7 +31378,8 @@ function validateWemlModel(m, model) {
|
|
|
30991
31378
|
function validateConstraint(constraint, info) {
|
|
30992
31379
|
if (info.value === void 0 || !info.valueRange) return;
|
|
30993
31380
|
if (constraint.kind === "pattern") {
|
|
30994
|
-
|
|
31381
|
+
const emptyIsInvalid = constraint.allowEmpty === false && info.value === "";
|
|
31382
|
+
if (emptyIsInvalid || info.value !== "" && constraint.pattern && !constraint.pattern.test(info.value)) {
|
|
30995
31383
|
push(info.valueRange, constraint.message, "error");
|
|
30996
31384
|
}
|
|
30997
31385
|
return;
|
|
@@ -31370,7 +31758,7 @@ function escapeSnippet(text) {
|
|
|
31370
31758
|
return text.replace(/\\/g, "\\\\").replace(/\$/g, "\\$").replace(/}/g, "\\}");
|
|
31371
31759
|
}
|
|
31372
31760
|
function buildWrapSnippet(tag, type, selection) {
|
|
31373
|
-
const attrs = type ? ` type="${type}"` : tag === "a" ? ' href="$1"' : (TAGS[tag]?.attributes ?? []).filter((a) => a.required).map((a) => ` ${a.name}="$1"`).join("");
|
|
31761
|
+
const attrs = type ? ` type="${type}"` : tag === "a" ? ' href="$1"' : tag === "w-color" ? ' foreground="$1"' : (TAGS[tag]?.attributes ?? []).filter((a) => a.required).map((a) => ` ${a.name}="$1"`).join("");
|
|
31374
31762
|
const inner = selection.length > 0 ? escapeSnippet(selection) : attrs.includes("$1") ? "$2" : "$1";
|
|
31375
31763
|
return `<${tag}${attrs}>${inner}</${tag}>`;
|
|
31376
31764
|
}
|
|
@@ -31523,7 +31911,7 @@ var WRAP_OPTIONS = [
|
|
|
31523
31911
|
tag: "w-format",
|
|
31524
31912
|
type: v.value
|
|
31525
31913
|
})),
|
|
31526
|
-
...["w-lang", "w-non-egw", "w-entity", "a"].map((t2) => ({ value: t2, label: t2, tag: t2 }))
|
|
31914
|
+
...["w-color", "w-lang", "w-non-egw", "w-entity", "a"].map((t2) => ({ value: t2, label: t2, tag: t2 }))
|
|
31527
31915
|
];
|
|
31528
31916
|
var SNIPPET_BUTTONS = [
|
|
31529
31917
|
{ label: "w-para", id: "w-para" },
|