@drghaliasri/butex 5.4.6 → 5.5.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/README.md +2 -2
- package/dist/document2.d.mts +20 -2
- package/dist/document2.d.ts +20 -2
- package/dist/document2.js +175 -12
- package/dist/document2.js.map +1 -1
- package/dist/document2.mjs +174 -12
- package/dist/document2.mjs.map +1 -1
- package/dist/react-document2.d.mts +23 -3
- package/dist/react-document2.d.ts +23 -3
- package/dist/react-document2.js +512 -47
- package/dist/react-document2.js.map +1 -1
- package/dist/react-document2.mjs +558 -93
- package/dist/react-document2.mjs.map +1 -1
- package/package.json +1 -1
package/dist/document2.mjs
CHANGED
|
@@ -1133,7 +1133,7 @@ function parseReferences(json) {
|
|
|
1133
1133
|
}
|
|
1134
1134
|
return references;
|
|
1135
1135
|
}
|
|
1136
|
-
function createInlineField2(value = "", mathObjects = [], options = {}, path = "$", diagnostics = []) {
|
|
1136
|
+
function createInlineField2(value = "", mathObjects = [], options = {}, path = "$", diagnostics = [], formats = []) {
|
|
1137
1137
|
const mode = options.mode ?? "english";
|
|
1138
1138
|
const spans = detectInlineSpans2(value);
|
|
1139
1139
|
const mathSpans = spans.filter((span) => span.kind === "math");
|
|
@@ -1145,7 +1145,7 @@ function createInlineField2(value = "", mathObjects = [], options = {}, path = "
|
|
|
1145
1145
|
}
|
|
1146
1146
|
for (const span of spans) {
|
|
1147
1147
|
if (span.start > index) {
|
|
1148
|
-
tokens
|
|
1148
|
+
pushFormattedTextTokens(tokens, value.slice(index, span.start), index, formats);
|
|
1149
1149
|
}
|
|
1150
1150
|
if (span.kind === "cite") {
|
|
1151
1151
|
tokens.push({
|
|
@@ -1201,9 +1201,81 @@ function createInlineField2(value = "", mathObjects = [], options = {}, path = "
|
|
|
1201
1201
|
index = span.end;
|
|
1202
1202
|
}
|
|
1203
1203
|
if (index < value.length || tokens.length === 0) {
|
|
1204
|
-
tokens
|
|
1204
|
+
pushFormattedTextTokens(tokens, value.slice(index), index, formats);
|
|
1205
|
+
}
|
|
1206
|
+
return { id: document2Id("field"), tokens: compactTextTokens(tokens) };
|
|
1207
|
+
}
|
|
1208
|
+
function styleFromFormat(format) {
|
|
1209
|
+
const style = {};
|
|
1210
|
+
if (format.bold === true) {
|
|
1211
|
+
style.bold = true;
|
|
1212
|
+
}
|
|
1213
|
+
if (format.italic === true) {
|
|
1214
|
+
style.italic = true;
|
|
1215
|
+
}
|
|
1216
|
+
if (format.underline === true) {
|
|
1217
|
+
style.underline = true;
|
|
1218
|
+
}
|
|
1219
|
+
return style.bold || style.italic || style.underline ? style : null;
|
|
1220
|
+
}
|
|
1221
|
+
function mergeTextStyle(base, added) {
|
|
1222
|
+
return {
|
|
1223
|
+
...base?.bold ? { bold: true } : {},
|
|
1224
|
+
...base?.italic ? { italic: true } : {},
|
|
1225
|
+
...base?.underline ? { underline: true } : {},
|
|
1226
|
+
...added.bold ? { bold: true } : {},
|
|
1227
|
+
...added.italic ? { italic: true } : {},
|
|
1228
|
+
...added.underline ? { underline: true } : {}
|
|
1229
|
+
};
|
|
1230
|
+
}
|
|
1231
|
+
function textStylesEqual(a, b) {
|
|
1232
|
+
return Boolean(a?.bold) === Boolean(b?.bold) && Boolean(a?.italic) === Boolean(b?.italic) && Boolean(a?.underline) === Boolean(b?.underline);
|
|
1233
|
+
}
|
|
1234
|
+
function compactTextTokens(tokens) {
|
|
1235
|
+
const compacted = [];
|
|
1236
|
+
for (const token of tokens) {
|
|
1237
|
+
const previous = compacted[compacted.length - 1];
|
|
1238
|
+
if (previous?.kind === "text" && token.kind === "text" && textStylesEqual(previous.style, token.style)) {
|
|
1239
|
+
previous.text += token.text;
|
|
1240
|
+
} else {
|
|
1241
|
+
compacted.push(token);
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
return compacted;
|
|
1245
|
+
}
|
|
1246
|
+
function styleKey(style) {
|
|
1247
|
+
return `${style?.bold ? "b" : ""}${style?.italic ? "i" : ""}${style?.underline ? "u" : ""}`;
|
|
1248
|
+
}
|
|
1249
|
+
function pushFormattedTextTokens(tokens, text, sourceStart, formats) {
|
|
1250
|
+
if (text.length === 0) {
|
|
1251
|
+
tokens.push({ id: document2Id("text"), kind: "text", text });
|
|
1252
|
+
return;
|
|
1253
|
+
}
|
|
1254
|
+
const styles = Array.from({ length: text.length });
|
|
1255
|
+
for (const format of formats) {
|
|
1256
|
+
const style = styleFromFormat(format);
|
|
1257
|
+
if (!style || !Number.isFinite(format.start) || !Number.isFinite(format.end)) {
|
|
1258
|
+
continue;
|
|
1259
|
+
}
|
|
1260
|
+
const start = Math.max(0, Math.min(text.length, Math.trunc(format.start) - sourceStart));
|
|
1261
|
+
const end = Math.max(0, Math.min(text.length, Math.trunc(format.end) - sourceStart));
|
|
1262
|
+
if (end <= start) {
|
|
1263
|
+
continue;
|
|
1264
|
+
}
|
|
1265
|
+
for (let index = start; index < end; index += 1) {
|
|
1266
|
+
styles[index] = mergeTextStyle(styles[index], style);
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
let chunkStart = 0;
|
|
1270
|
+
for (let index = 1; index <= text.length; index += 1) {
|
|
1271
|
+
if (index < text.length && styleKey(styles[index]) === styleKey(styles[chunkStart])) {
|
|
1272
|
+
continue;
|
|
1273
|
+
}
|
|
1274
|
+
const chunk = text.slice(chunkStart, index);
|
|
1275
|
+
const style = styles[chunkStart];
|
|
1276
|
+
tokens.push({ id: document2Id("text"), kind: "text", text: chunk, ...style ? { style } : {} });
|
|
1277
|
+
chunkStart = index;
|
|
1205
1278
|
}
|
|
1206
|
-
return { id: document2Id("field"), tokens };
|
|
1207
1279
|
}
|
|
1208
1280
|
function closingForList(command) {
|
|
1209
1281
|
return command === "\\begin{itemize}" ? "\\end{itemize}" : "\\end{enumerate}";
|
|
@@ -1214,7 +1286,7 @@ function parseTextBlock(json, options, path, diagnostics) {
|
|
|
1214
1286
|
id: document2Id("block"),
|
|
1215
1287
|
kind: "textBlock",
|
|
1216
1288
|
command: json.command,
|
|
1217
|
-
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics),
|
|
1289
|
+
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics, json.command === "\\paragraph" ? json.formats ?? [] : []),
|
|
1218
1290
|
...json.centered === true ? { centered: true } : {}
|
|
1219
1291
|
};
|
|
1220
1292
|
}
|
|
@@ -1223,7 +1295,7 @@ function parseListItem(json, options, path, diagnostics) {
|
|
|
1223
1295
|
const blocksJson = Array.isArray(json.blocks) ? json.blocks : [];
|
|
1224
1296
|
return {
|
|
1225
1297
|
id: document2Id("item"),
|
|
1226
|
-
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics),
|
|
1298
|
+
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics, json.formats ?? []),
|
|
1227
1299
|
blocks: blocksJson.map((block, index) => parseBlock(asBlockJson(block), options, `${path}.blocks[${String(index)}]`, diagnostics))
|
|
1228
1300
|
};
|
|
1229
1301
|
}
|
|
@@ -1256,7 +1328,8 @@ function parseTableBlock(json, options, path, diagnostics) {
|
|
|
1256
1328
|
const spanCount = detectMathSpans2(value).length;
|
|
1257
1329
|
const cellMathObjects = mathObjects.slice(mathObjectIndex, mathObjectIndex + spanCount);
|
|
1258
1330
|
mathObjectIndex += spanCount;
|
|
1259
|
-
|
|
1331
|
+
const cellFormats = json.cell_formats?.[rowIndex]?.[columnIndex] ?? [];
|
|
1332
|
+
return createInlineField2(value, cellMathObjects, options, `${path}.rows[${String(rowIndex)}][${String(columnIndex)}]`, diagnostics, cellFormats);
|
|
1260
1333
|
});
|
|
1261
1334
|
});
|
|
1262
1335
|
if (mathObjects.length > 0 && mathObjects.length !== mathObjectIndex) {
|
|
@@ -4296,6 +4369,79 @@ function normalizeFieldTokens(tokens) {
|
|
|
4296
4369
|
}
|
|
4297
4370
|
return tokens;
|
|
4298
4371
|
}
|
|
4372
|
+
function textStylesEqual2(a, b) {
|
|
4373
|
+
return Boolean(a?.bold) === Boolean(b?.bold) && Boolean(a?.italic) === Boolean(b?.italic) && Boolean(a?.underline) === Boolean(b?.underline);
|
|
4374
|
+
}
|
|
4375
|
+
function compactAdjacentTextTokens(tokens) {
|
|
4376
|
+
const compacted = [];
|
|
4377
|
+
for (const token of tokens) {
|
|
4378
|
+
const previous = compacted[compacted.length - 1];
|
|
4379
|
+
if (previous?.kind === "text" && token.kind === "text" && textStylesEqual2(previous.style, token.style)) {
|
|
4380
|
+
previous.text += token.text;
|
|
4381
|
+
} else {
|
|
4382
|
+
compacted.push(token);
|
|
4383
|
+
}
|
|
4384
|
+
}
|
|
4385
|
+
return normalizeFieldTokens(compacted);
|
|
4386
|
+
}
|
|
4387
|
+
function withoutEmptyStyle(style) {
|
|
4388
|
+
const next = {};
|
|
4389
|
+
if (style.bold) {
|
|
4390
|
+
next.bold = true;
|
|
4391
|
+
}
|
|
4392
|
+
if (style.italic) {
|
|
4393
|
+
next.italic = true;
|
|
4394
|
+
}
|
|
4395
|
+
if (style.underline) {
|
|
4396
|
+
next.underline = true;
|
|
4397
|
+
}
|
|
4398
|
+
return next.bold || next.italic || next.underline ? next : void 0;
|
|
4399
|
+
}
|
|
4400
|
+
function textTokenPart(text, style, id = document2Id("text")) {
|
|
4401
|
+
return { id, kind: "text", text, ...style ? { style } : {} };
|
|
4402
|
+
}
|
|
4403
|
+
function toggleTextTokenStyle(document2, fieldId, tokenId, selectionStart, selectionEnd, styleName) {
|
|
4404
|
+
if (selectionEnd <= selectionStart) {
|
|
4405
|
+
return document2;
|
|
4406
|
+
}
|
|
4407
|
+
const next = cloneDocument(document2);
|
|
4408
|
+
visitFields(next.blocks, (field) => {
|
|
4409
|
+
if (field.id !== fieldId) {
|
|
4410
|
+
return false;
|
|
4411
|
+
}
|
|
4412
|
+
const tokenIndex = field.tokens.findIndex((entry) => entry.id === tokenId && entry.kind === "text");
|
|
4413
|
+
if (tokenIndex < 0) {
|
|
4414
|
+
return true;
|
|
4415
|
+
}
|
|
4416
|
+
const token = field.tokens[tokenIndex];
|
|
4417
|
+
const start = Math.max(0, Math.min(token.text.length, selectionStart));
|
|
4418
|
+
const end = Math.max(0, Math.min(token.text.length, selectionEnd));
|
|
4419
|
+
if (end <= start) {
|
|
4420
|
+
return true;
|
|
4421
|
+
}
|
|
4422
|
+
const selectedStyle = token.style ?? {};
|
|
4423
|
+
const enabled = selectedStyle[styleName] === true;
|
|
4424
|
+
const nextStyle = withoutEmptyStyle({ ...selectedStyle, [styleName]: enabled ? void 0 : true });
|
|
4425
|
+
const parts = [];
|
|
4426
|
+
const before = token.text.slice(0, start);
|
|
4427
|
+
const selected = token.text.slice(start, end);
|
|
4428
|
+
const after = token.text.slice(end);
|
|
4429
|
+
if (before.length > 0) {
|
|
4430
|
+
parts.push(textTokenPart(before, token.style, token.id));
|
|
4431
|
+
}
|
|
4432
|
+
parts.push(textTokenPart(selected, nextStyle, before.length > 0 ? document2Id("text") : token.id));
|
|
4433
|
+
if (after.length > 0) {
|
|
4434
|
+
parts.push(textTokenPart(after, token.style));
|
|
4435
|
+
}
|
|
4436
|
+
field.tokens = compactAdjacentTextTokens([
|
|
4437
|
+
...field.tokens.slice(0, tokenIndex),
|
|
4438
|
+
...parts,
|
|
4439
|
+
...field.tokens.slice(tokenIndex + 1)
|
|
4440
|
+
]);
|
|
4441
|
+
return true;
|
|
4442
|
+
});
|
|
4443
|
+
return next;
|
|
4444
|
+
}
|
|
4299
4445
|
function stitchTextAroundRemovedToken(tokens, index) {
|
|
4300
4446
|
const before = tokens[index - 1];
|
|
4301
4447
|
const after = tokens[index + 1];
|
|
@@ -4323,8 +4469,8 @@ function removeMathTokenById(document2, tokenId) {
|
|
|
4323
4469
|
function splitTextTokenAt(token, offset) {
|
|
4324
4470
|
const safeOffset = Math.max(0, Math.min(offset, token.text.length));
|
|
4325
4471
|
return [
|
|
4326
|
-
{ id: token.id, kind: "text", text: token.text.slice(0, safeOffset) },
|
|
4327
|
-
{ id: document2Id("text"), kind: "text", text: token.text.slice(safeOffset) }
|
|
4472
|
+
{ id: token.id, kind: "text", text: token.text.slice(0, safeOffset), ...token.style ? { style: token.style } : {} },
|
|
4473
|
+
{ id: document2Id("text"), kind: "text", text: token.text.slice(safeOffset), ...token.style ? { style: token.style } : {} }
|
|
4328
4474
|
];
|
|
4329
4475
|
}
|
|
4330
4476
|
function insertMathTokenAtCaret(document2, fieldId, textTokenId, caretOffset, session, opening = "$", closing = "$", side = "arabic") {
|
|
@@ -5066,9 +5212,22 @@ function mathBodyLatex(token) {
|
|
|
5066
5212
|
const rendered = renderMathNodeLatex(token.math);
|
|
5067
5213
|
return stripDisplayMathDelimiters(rendered);
|
|
5068
5214
|
}
|
|
5215
|
+
function styledTextLatex(text, style) {
|
|
5216
|
+
let output = text;
|
|
5217
|
+
if (style?.bold) {
|
|
5218
|
+
output = `\\textbf{${output}}`;
|
|
5219
|
+
}
|
|
5220
|
+
if (style?.italic) {
|
|
5221
|
+
output = `\\textit{${output}}`;
|
|
5222
|
+
}
|
|
5223
|
+
if (style?.underline) {
|
|
5224
|
+
output = `\\underline{${output}}`;
|
|
5225
|
+
}
|
|
5226
|
+
return output;
|
|
5227
|
+
}
|
|
5069
5228
|
function tokenLatex(token) {
|
|
5070
5229
|
if (token.kind === "text") {
|
|
5071
|
-
return token.text;
|
|
5230
|
+
return styledTextLatex(token.text, token.style);
|
|
5072
5231
|
}
|
|
5073
5232
|
if (token.kind === "cite") {
|
|
5074
5233
|
return citeTokenLatex(token.keys);
|
|
@@ -5092,7 +5251,9 @@ function inlineFieldLatex(field) {
|
|
|
5092
5251
|
return field.tokens.map((token) => tokenLatex(token)).join("");
|
|
5093
5252
|
}
|
|
5094
5253
|
function textBlockLatex(block) {
|
|
5095
|
-
const
|
|
5254
|
+
const content = inlineFieldLatex(block.field);
|
|
5255
|
+
const body = block.command === "\\paragraph" ? `\\par
|
|
5256
|
+
${content}` : `${block.command}{${content}}`;
|
|
5096
5257
|
if (block.command === "\\paragraph" && block.centered) {
|
|
5097
5258
|
return `\\begin{center}
|
|
5098
5259
|
${body}
|
|
@@ -5344,7 +5505,7 @@ function mathTex(token, equationSide) {
|
|
|
5344
5505
|
function previewInlines(field, islands, output, equationSide, document2, previewOptions) {
|
|
5345
5506
|
return field.tokens.map((token) => {
|
|
5346
5507
|
if (token.kind === "text") {
|
|
5347
|
-
return { kind: "text", text: token.text };
|
|
5508
|
+
return { kind: "text", text: token.text, ...token.style ? { style: token.style } : {} };
|
|
5348
5509
|
}
|
|
5349
5510
|
if (token.kind === "cite") {
|
|
5350
5511
|
return {
|
|
@@ -5625,6 +5786,7 @@ export {
|
|
|
5625
5786
|
setDocument2References,
|
|
5626
5787
|
stripDisplayMathDelimiters,
|
|
5627
5788
|
toggleBlockInSelection,
|
|
5789
|
+
toggleTextTokenStyle,
|
|
5628
5790
|
updateCiteTokenKeys,
|
|
5629
5791
|
updateDocument2ImageMeta,
|
|
5630
5792
|
updateDocument2ImageValue,
|