@drghaliasri/butex 5.4.5 → 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 +176 -13
- package/dist/document2.js.map +1 -1
- package/dist/document2.mjs +175 -13
- 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 +513 -48
- package/dist/react-document2.js.map +1 -1
- package/dist/react-document2.mjs +559 -94
- package/dist/react-document2.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react-document2.js
CHANGED
|
@@ -1168,7 +1168,7 @@ function parseReferences(json) {
|
|
|
1168
1168
|
}
|
|
1169
1169
|
return references;
|
|
1170
1170
|
}
|
|
1171
|
-
function createInlineField2(value = "", mathObjects = [], options = {}, path = "$", diagnostics = []) {
|
|
1171
|
+
function createInlineField2(value = "", mathObjects = [], options = {}, path = "$", diagnostics = [], formats = []) {
|
|
1172
1172
|
const mode = options.mode ?? "english";
|
|
1173
1173
|
const spans = detectInlineSpans2(value);
|
|
1174
1174
|
const mathSpans = spans.filter((span) => span.kind === "math");
|
|
@@ -1180,7 +1180,7 @@ function createInlineField2(value = "", mathObjects = [], options = {}, path = "
|
|
|
1180
1180
|
}
|
|
1181
1181
|
for (const span of spans) {
|
|
1182
1182
|
if (span.start > index) {
|
|
1183
|
-
tokens
|
|
1183
|
+
pushFormattedTextTokens(tokens, value.slice(index, span.start), index, formats);
|
|
1184
1184
|
}
|
|
1185
1185
|
if (span.kind === "cite") {
|
|
1186
1186
|
tokens.push({
|
|
@@ -1236,9 +1236,81 @@ function createInlineField2(value = "", mathObjects = [], options = {}, path = "
|
|
|
1236
1236
|
index = span.end;
|
|
1237
1237
|
}
|
|
1238
1238
|
if (index < value.length || tokens.length === 0) {
|
|
1239
|
-
tokens
|
|
1239
|
+
pushFormattedTextTokens(tokens, value.slice(index), index, formats);
|
|
1240
|
+
}
|
|
1241
|
+
return { id: document2Id("field"), tokens: compactTextTokens(tokens) };
|
|
1242
|
+
}
|
|
1243
|
+
function styleFromFormat(format) {
|
|
1244
|
+
const style = {};
|
|
1245
|
+
if (format.bold === true) {
|
|
1246
|
+
style.bold = true;
|
|
1247
|
+
}
|
|
1248
|
+
if (format.italic === true) {
|
|
1249
|
+
style.italic = true;
|
|
1250
|
+
}
|
|
1251
|
+
if (format.underline === true) {
|
|
1252
|
+
style.underline = true;
|
|
1253
|
+
}
|
|
1254
|
+
return style.bold || style.italic || style.underline ? style : null;
|
|
1255
|
+
}
|
|
1256
|
+
function mergeTextStyle(base, added) {
|
|
1257
|
+
return {
|
|
1258
|
+
...base?.bold ? { bold: true } : {},
|
|
1259
|
+
...base?.italic ? { italic: true } : {},
|
|
1260
|
+
...base?.underline ? { underline: true } : {},
|
|
1261
|
+
...added.bold ? { bold: true } : {},
|
|
1262
|
+
...added.italic ? { italic: true } : {},
|
|
1263
|
+
...added.underline ? { underline: true } : {}
|
|
1264
|
+
};
|
|
1265
|
+
}
|
|
1266
|
+
function textStylesEqual(a, b) {
|
|
1267
|
+
return Boolean(a?.bold) === Boolean(b?.bold) && Boolean(a?.italic) === Boolean(b?.italic) && Boolean(a?.underline) === Boolean(b?.underline);
|
|
1268
|
+
}
|
|
1269
|
+
function compactTextTokens(tokens) {
|
|
1270
|
+
const compacted = [];
|
|
1271
|
+
for (const token of tokens) {
|
|
1272
|
+
const previous = compacted[compacted.length - 1];
|
|
1273
|
+
if (previous?.kind === "text" && token.kind === "text" && textStylesEqual(previous.style, token.style)) {
|
|
1274
|
+
previous.text += token.text;
|
|
1275
|
+
} else {
|
|
1276
|
+
compacted.push(token);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
return compacted;
|
|
1280
|
+
}
|
|
1281
|
+
function styleKey(style) {
|
|
1282
|
+
return `${style?.bold ? "b" : ""}${style?.italic ? "i" : ""}${style?.underline ? "u" : ""}`;
|
|
1283
|
+
}
|
|
1284
|
+
function pushFormattedTextTokens(tokens, text, sourceStart, formats) {
|
|
1285
|
+
if (text.length === 0) {
|
|
1286
|
+
tokens.push({ id: document2Id("text"), kind: "text", text });
|
|
1287
|
+
return;
|
|
1288
|
+
}
|
|
1289
|
+
const styles = Array.from({ length: text.length });
|
|
1290
|
+
for (const format of formats) {
|
|
1291
|
+
const style = styleFromFormat(format);
|
|
1292
|
+
if (!style || !Number.isFinite(format.start) || !Number.isFinite(format.end)) {
|
|
1293
|
+
continue;
|
|
1294
|
+
}
|
|
1295
|
+
const start = Math.max(0, Math.min(text.length, Math.trunc(format.start) - sourceStart));
|
|
1296
|
+
const end = Math.max(0, Math.min(text.length, Math.trunc(format.end) - sourceStart));
|
|
1297
|
+
if (end <= start) {
|
|
1298
|
+
continue;
|
|
1299
|
+
}
|
|
1300
|
+
for (let index = start; index < end; index += 1) {
|
|
1301
|
+
styles[index] = mergeTextStyle(styles[index], style);
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
let chunkStart = 0;
|
|
1305
|
+
for (let index = 1; index <= text.length; index += 1) {
|
|
1306
|
+
if (index < text.length && styleKey(styles[index]) === styleKey(styles[chunkStart])) {
|
|
1307
|
+
continue;
|
|
1308
|
+
}
|
|
1309
|
+
const chunk = text.slice(chunkStart, index);
|
|
1310
|
+
const style = styles[chunkStart];
|
|
1311
|
+
tokens.push({ id: document2Id("text"), kind: "text", text: chunk, ...style ? { style } : {} });
|
|
1312
|
+
chunkStart = index;
|
|
1240
1313
|
}
|
|
1241
|
-
return { id: document2Id("field"), tokens };
|
|
1242
1314
|
}
|
|
1243
1315
|
function closingForList(command) {
|
|
1244
1316
|
return command === "\\begin{itemize}" ? "\\end{itemize}" : "\\end{enumerate}";
|
|
@@ -1249,7 +1321,7 @@ function parseTextBlock(json, options, path, diagnostics) {
|
|
|
1249
1321
|
id: document2Id("block"),
|
|
1250
1322
|
kind: "textBlock",
|
|
1251
1323
|
command: json.command,
|
|
1252
|
-
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics),
|
|
1324
|
+
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics, json.command === "\\paragraph" ? json.formats ?? [] : []),
|
|
1253
1325
|
...json.centered === true ? { centered: true } : {}
|
|
1254
1326
|
};
|
|
1255
1327
|
}
|
|
@@ -1258,7 +1330,7 @@ function parseListItem(json, options, path, diagnostics) {
|
|
|
1258
1330
|
const blocksJson = Array.isArray(json.blocks) ? json.blocks : [];
|
|
1259
1331
|
return {
|
|
1260
1332
|
id: document2Id("item"),
|
|
1261
|
-
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics),
|
|
1333
|
+
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics, json.formats ?? []),
|
|
1262
1334
|
blocks: blocksJson.map((block, index) => parseBlock(asBlockJson(block), options, `${path}.blocks[${String(index)}]`, diagnostics))
|
|
1263
1335
|
};
|
|
1264
1336
|
}
|
|
@@ -1291,7 +1363,8 @@ function parseTableBlock(json, options, path, diagnostics) {
|
|
|
1291
1363
|
const spanCount = detectMathSpans2(value).length;
|
|
1292
1364
|
const cellMathObjects = mathObjects.slice(mathObjectIndex, mathObjectIndex + spanCount);
|
|
1293
1365
|
mathObjectIndex += spanCount;
|
|
1294
|
-
|
|
1366
|
+
const cellFormats = json.cell_formats?.[rowIndex]?.[columnIndex] ?? [];
|
|
1367
|
+
return createInlineField2(value, cellMathObjects, options, `${path}.rows[${String(rowIndex)}][${String(columnIndex)}]`, diagnostics, cellFormats);
|
|
1295
1368
|
});
|
|
1296
1369
|
});
|
|
1297
1370
|
if (mathObjects.length > 0 && mathObjects.length !== mathObjectIndex) {
|
|
@@ -8116,6 +8189,79 @@ function normalizeFieldTokens(tokens) {
|
|
|
8116
8189
|
}
|
|
8117
8190
|
return tokens;
|
|
8118
8191
|
}
|
|
8192
|
+
function textStylesEqual2(a, b) {
|
|
8193
|
+
return Boolean(a?.bold) === Boolean(b?.bold) && Boolean(a?.italic) === Boolean(b?.italic) && Boolean(a?.underline) === Boolean(b?.underline);
|
|
8194
|
+
}
|
|
8195
|
+
function compactAdjacentTextTokens(tokens) {
|
|
8196
|
+
const compacted = [];
|
|
8197
|
+
for (const token of tokens) {
|
|
8198
|
+
const previous = compacted[compacted.length - 1];
|
|
8199
|
+
if (previous?.kind === "text" && token.kind === "text" && textStylesEqual2(previous.style, token.style)) {
|
|
8200
|
+
previous.text += token.text;
|
|
8201
|
+
} else {
|
|
8202
|
+
compacted.push(token);
|
|
8203
|
+
}
|
|
8204
|
+
}
|
|
8205
|
+
return normalizeFieldTokens(compacted);
|
|
8206
|
+
}
|
|
8207
|
+
function withoutEmptyStyle(style) {
|
|
8208
|
+
const next = {};
|
|
8209
|
+
if (style.bold) {
|
|
8210
|
+
next.bold = true;
|
|
8211
|
+
}
|
|
8212
|
+
if (style.italic) {
|
|
8213
|
+
next.italic = true;
|
|
8214
|
+
}
|
|
8215
|
+
if (style.underline) {
|
|
8216
|
+
next.underline = true;
|
|
8217
|
+
}
|
|
8218
|
+
return next.bold || next.italic || next.underline ? next : void 0;
|
|
8219
|
+
}
|
|
8220
|
+
function textTokenPart(text, style, id = document2Id("text")) {
|
|
8221
|
+
return { id, kind: "text", text, ...style ? { style } : {} };
|
|
8222
|
+
}
|
|
8223
|
+
function toggleTextTokenStyle(document2, fieldId, tokenId, selectionStart, selectionEnd, styleName) {
|
|
8224
|
+
if (selectionEnd <= selectionStart) {
|
|
8225
|
+
return document2;
|
|
8226
|
+
}
|
|
8227
|
+
const next = cloneDocument(document2);
|
|
8228
|
+
visitFields(next.blocks, (field) => {
|
|
8229
|
+
if (field.id !== fieldId) {
|
|
8230
|
+
return false;
|
|
8231
|
+
}
|
|
8232
|
+
const tokenIndex = field.tokens.findIndex((entry) => entry.id === tokenId && entry.kind === "text");
|
|
8233
|
+
if (tokenIndex < 0) {
|
|
8234
|
+
return true;
|
|
8235
|
+
}
|
|
8236
|
+
const token = field.tokens[tokenIndex];
|
|
8237
|
+
const start = Math.max(0, Math.min(token.text.length, selectionStart));
|
|
8238
|
+
const end = Math.max(0, Math.min(token.text.length, selectionEnd));
|
|
8239
|
+
if (end <= start) {
|
|
8240
|
+
return true;
|
|
8241
|
+
}
|
|
8242
|
+
const selectedStyle = token.style ?? {};
|
|
8243
|
+
const enabled = selectedStyle[styleName] === true;
|
|
8244
|
+
const nextStyle = withoutEmptyStyle({ ...selectedStyle, [styleName]: enabled ? void 0 : true });
|
|
8245
|
+
const parts = [];
|
|
8246
|
+
const before = token.text.slice(0, start);
|
|
8247
|
+
const selected = token.text.slice(start, end);
|
|
8248
|
+
const after = token.text.slice(end);
|
|
8249
|
+
if (before.length > 0) {
|
|
8250
|
+
parts.push(textTokenPart(before, token.style, token.id));
|
|
8251
|
+
}
|
|
8252
|
+
parts.push(textTokenPart(selected, nextStyle, before.length > 0 ? document2Id("text") : token.id));
|
|
8253
|
+
if (after.length > 0) {
|
|
8254
|
+
parts.push(textTokenPart(after, token.style));
|
|
8255
|
+
}
|
|
8256
|
+
field.tokens = compactAdjacentTextTokens([
|
|
8257
|
+
...field.tokens.slice(0, tokenIndex),
|
|
8258
|
+
...parts,
|
|
8259
|
+
...field.tokens.slice(tokenIndex + 1)
|
|
8260
|
+
]);
|
|
8261
|
+
return true;
|
|
8262
|
+
});
|
|
8263
|
+
return next;
|
|
8264
|
+
}
|
|
8119
8265
|
function stitchTextAroundRemovedToken(tokens, index) {
|
|
8120
8266
|
const before = tokens[index - 1];
|
|
8121
8267
|
const after = tokens[index + 1];
|
|
@@ -8143,8 +8289,8 @@ function removeMathTokenById(document2, tokenId) {
|
|
|
8143
8289
|
function splitTextTokenAt(token, offset) {
|
|
8144
8290
|
const safeOffset = Math.max(0, Math.min(offset, token.text.length));
|
|
8145
8291
|
return [
|
|
8146
|
-
{ id: token.id, kind: "text", text: token.text.slice(0, safeOffset) },
|
|
8147
|
-
{ id: document2Id("text"), kind: "text", text: token.text.slice(safeOffset) }
|
|
8292
|
+
{ id: token.id, kind: "text", text: token.text.slice(0, safeOffset), ...token.style ? { style: token.style } : {} },
|
|
8293
|
+
{ id: document2Id("text"), kind: "text", text: token.text.slice(safeOffset), ...token.style ? { style: token.style } : {} }
|
|
8148
8294
|
];
|
|
8149
8295
|
}
|
|
8150
8296
|
function insertMathTokenAtCaret(document2, fieldId, textTokenId, caretOffset, session, opening = "$", closing = "$", side = "arabic") {
|
|
@@ -8716,7 +8862,7 @@ function arabicXeLatexPreambleCmd() {
|
|
|
8716
8862
|
\newcommand{\horzbar}{\rule[.5ex]{2.5ex}{0.5pt}}
|
|
8717
8863
|
|
|
8718
8864
|
|
|
8719
|
-
\newcommand{\butexreflect}[1]{
|
|
8865
|
+
\newcommand{\butexreflect}[1]{\tikz[baseline=(n.base)]{\node[inner sep=0pt,outer sep=0pt,xscale=-1](n){#1};}}
|
|
8720
8866
|
|
|
8721
8867
|
\newcommand{\arabsqrt}[2]{\butexreflect{\(\sqrt[\butexreflect{\(#1\)}]{\butexreflect{\(#2\)}}\)}}
|
|
8722
8868
|
\newcommand{\arabvec}[1]{\butexreflect{$\vec{\butexreflect{$#1$}}$}}
|
|
@@ -8852,9 +8998,22 @@ function mathBodyLatex(token) {
|
|
|
8852
8998
|
const rendered = renderMathNodeLatex(token.math);
|
|
8853
8999
|
return stripDisplayMathDelimiters(rendered);
|
|
8854
9000
|
}
|
|
9001
|
+
function styledTextLatex(text, style) {
|
|
9002
|
+
let output = text;
|
|
9003
|
+
if (style?.bold) {
|
|
9004
|
+
output = `\\textbf{${output}}`;
|
|
9005
|
+
}
|
|
9006
|
+
if (style?.italic) {
|
|
9007
|
+
output = `\\textit{${output}}`;
|
|
9008
|
+
}
|
|
9009
|
+
if (style?.underline) {
|
|
9010
|
+
output = `\\underline{${output}}`;
|
|
9011
|
+
}
|
|
9012
|
+
return output;
|
|
9013
|
+
}
|
|
8855
9014
|
function tokenLatex(token) {
|
|
8856
9015
|
if (token.kind === "text") {
|
|
8857
|
-
return token.text;
|
|
9016
|
+
return styledTextLatex(token.text, token.style);
|
|
8858
9017
|
}
|
|
8859
9018
|
if (token.kind === "cite") {
|
|
8860
9019
|
return citeTokenLatex(token.keys);
|
|
@@ -8878,7 +9037,9 @@ function inlineFieldLatex(field) {
|
|
|
8878
9037
|
return field.tokens.map((token) => tokenLatex(token)).join("");
|
|
8879
9038
|
}
|
|
8880
9039
|
function textBlockLatex(block) {
|
|
8881
|
-
const
|
|
9040
|
+
const content = inlineFieldLatex(block.field);
|
|
9041
|
+
const body = block.command === "\\paragraph" ? `\\par
|
|
9042
|
+
${content}` : `${block.command}{${content}}`;
|
|
8882
9043
|
if (block.command === "\\paragraph" && block.centered) {
|
|
8883
9044
|
return `\\begin{center}
|
|
8884
9045
|
${body}
|
|
@@ -9130,7 +9291,7 @@ function mathTex(token, equationSide) {
|
|
|
9130
9291
|
function previewInlines(field, islands, output, equationSide, document2, previewOptions) {
|
|
9131
9292
|
return field.tokens.map((token) => {
|
|
9132
9293
|
if (token.kind === "text") {
|
|
9133
|
-
return { kind: "text", text: token.text };
|
|
9294
|
+
return { kind: "text", text: token.text, ...token.style ? { style: token.style } : {} };
|
|
9134
9295
|
}
|
|
9135
9296
|
if (token.kind === "cite") {
|
|
9136
9297
|
return {
|
|
@@ -9306,6 +9467,10 @@ var DOCUMENT2_MESSAGES = {
|
|
|
9306
9467
|
redo: "\u0625\u0639\u0627\u062F\u0629",
|
|
9307
9468
|
structure: "\u0647\u064A\u0643\u0644",
|
|
9308
9469
|
content: "\u0645\u062D\u062A\u0648\u0649",
|
|
9470
|
+
textFormatting: "\u062A\u0646\u0633\u064A\u0642 \u0627\u0644\u0646\u0635",
|
|
9471
|
+
bold: "\u063A\u0627\u0645\u0642",
|
|
9472
|
+
italic: "\u0645\u0627\u0626\u0644",
|
|
9473
|
+
underline: "\u062A\u062D\u062A\u0647 \u062E\u0637",
|
|
9309
9474
|
equations: "\u0645\u0639\u0627\u062F\u0644\u0627\u062A",
|
|
9310
9475
|
citations: "\u0627\u0642\u062A\u0628\u0627\u0633\u0627\u062A \u0648\u0645\u0631\u0627\u062C\u0639",
|
|
9311
9476
|
lists: "\u0642\u0648\u0627\u0626\u0645",
|
|
@@ -9445,6 +9610,10 @@ var DOCUMENT2_MESSAGES = {
|
|
|
9445
9610
|
redo: "Redo",
|
|
9446
9611
|
structure: "Structure",
|
|
9447
9612
|
content: "Content",
|
|
9613
|
+
textFormatting: "Text formatting",
|
|
9614
|
+
bold: "Bold",
|
|
9615
|
+
italic: "Italic",
|
|
9616
|
+
underline: "Underline",
|
|
9448
9617
|
equations: "Equations",
|
|
9449
9618
|
citations: "Citations and references",
|
|
9450
9619
|
lists: "Lists",
|
|
@@ -10483,7 +10652,9 @@ function rememberCaret(element, blockId, fieldId, tokenId, onFieldFocus) {
|
|
|
10483
10652
|
if (!blockId || !onFieldFocus) {
|
|
10484
10653
|
return;
|
|
10485
10654
|
}
|
|
10486
|
-
|
|
10655
|
+
const selectionStart = element.selectionStart ?? element.value.length;
|
|
10656
|
+
const selectionEnd = element.selectionEnd ?? selectionStart;
|
|
10657
|
+
onFieldFocus(blockId, fieldId, tokenId, selectionEnd, selectionStart, selectionEnd);
|
|
10487
10658
|
}
|
|
10488
10659
|
function fitTextareaHeight(element) {
|
|
10489
10660
|
if (!element) {
|
|
@@ -10617,6 +10788,9 @@ function InlineField({
|
|
|
10617
10788
|
{
|
|
10618
10789
|
className: "butex-document2-widget__inline-text",
|
|
10619
10790
|
value: token.text,
|
|
10791
|
+
"data-bold": token.style?.bold === true ? "true" : void 0,
|
|
10792
|
+
"data-italic": token.style?.italic === true ? "true" : void 0,
|
|
10793
|
+
"data-underline": token.style?.underline === true ? "true" : void 0,
|
|
10620
10794
|
dir: documentDirection,
|
|
10621
10795
|
"aria-label": messages.text,
|
|
10622
10796
|
rows: 1,
|
|
@@ -11413,8 +11587,11 @@ function DocumentInsertToolbar({
|
|
|
11413
11587
|
selectionCount = 0,
|
|
11414
11588
|
canMoveSelectionUp = false,
|
|
11415
11589
|
canMoveSelectionDown = false,
|
|
11590
|
+
canFormatText = false,
|
|
11591
|
+
activeTextStyles = {},
|
|
11416
11592
|
onUndo,
|
|
11417
11593
|
onRedo,
|
|
11594
|
+
onToggleTextStyle,
|
|
11418
11595
|
onMoveSelectionUp,
|
|
11419
11596
|
onMoveSelectionDown,
|
|
11420
11597
|
onDeleteSelection,
|
|
@@ -11438,6 +11615,56 @@ function DocumentInsertToolbar({
|
|
|
11438
11615
|
}) {
|
|
11439
11616
|
const messages = document2Messages(uiLocale);
|
|
11440
11617
|
const [digitMenuOpen, setDigitMenuOpen] = (0, import_react7.useState)(false);
|
|
11618
|
+
const [referencesMenuOpen, setReferencesMenuOpen] = (0, import_react7.useState)(false);
|
|
11619
|
+
const referencesMenuRef = (0, import_react7.useRef)(null);
|
|
11620
|
+
const referencesTriggerRef = (0, import_react7.useRef)(null);
|
|
11621
|
+
(0, import_react7.useEffect)(() => {
|
|
11622
|
+
if (!referencesMenuOpen) {
|
|
11623
|
+
return;
|
|
11624
|
+
}
|
|
11625
|
+
referencesMenuRef.current?.querySelector('[role="menuitem"]')?.focus();
|
|
11626
|
+
const closeOnOutsideClick = (event) => {
|
|
11627
|
+
if (!referencesMenuRef.current?.contains(event.target)) {
|
|
11628
|
+
setReferencesMenuOpen(false);
|
|
11629
|
+
}
|
|
11630
|
+
};
|
|
11631
|
+
const closeOnEscape = (event) => {
|
|
11632
|
+
if (event.key === "Escape") {
|
|
11633
|
+
setReferencesMenuOpen(false);
|
|
11634
|
+
referencesTriggerRef.current?.focus();
|
|
11635
|
+
}
|
|
11636
|
+
};
|
|
11637
|
+
document.addEventListener("mousedown", closeOnOutsideClick);
|
|
11638
|
+
document.addEventListener("keydown", closeOnEscape);
|
|
11639
|
+
return () => {
|
|
11640
|
+
document.removeEventListener("mousedown", closeOnOutsideClick);
|
|
11641
|
+
document.removeEventListener("keydown", closeOnEscape);
|
|
11642
|
+
};
|
|
11643
|
+
}, [referencesMenuOpen]);
|
|
11644
|
+
function runReferenceAction(action) {
|
|
11645
|
+
setReferencesMenuOpen(false);
|
|
11646
|
+
action();
|
|
11647
|
+
}
|
|
11648
|
+
function moveReferenceMenuFocus(event) {
|
|
11649
|
+
if (!["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
|
|
11650
|
+
return;
|
|
11651
|
+
}
|
|
11652
|
+
const items = Array.from(event.currentTarget.querySelectorAll('[role="menuitem"]'));
|
|
11653
|
+
if (items.length === 0) {
|
|
11654
|
+
return;
|
|
11655
|
+
}
|
|
11656
|
+
event.preventDefault();
|
|
11657
|
+
const currentIndex = items.indexOf(document.activeElement);
|
|
11658
|
+
if (event.key === "Home") {
|
|
11659
|
+
items[0]?.focus();
|
|
11660
|
+
} else if (event.key === "End") {
|
|
11661
|
+
items[items.length - 1]?.focus();
|
|
11662
|
+
} else {
|
|
11663
|
+
const change = event.key === "ArrowDown" ? 1 : -1;
|
|
11664
|
+
const nextIndex = (currentIndex + change + items.length) % items.length;
|
|
11665
|
+
items[nextIndex]?.focus();
|
|
11666
|
+
}
|
|
11667
|
+
}
|
|
11441
11668
|
function digitTitle(id) {
|
|
11442
11669
|
if (id === "arabicIndic") {
|
|
11443
11670
|
return messages.arabicIndicDigits;
|
|
@@ -11495,6 +11722,50 @@ function DocumentInsertToolbar({
|
|
|
11495
11722
|
messages.selectedBlockCount
|
|
11496
11723
|
] }) : null
|
|
11497
11724
|
] }),
|
|
11725
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "butex-document2-widget__toolbar-group", role: "group", "aria-label": messages.textFormatting, children: [
|
|
11726
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
11727
|
+
"button",
|
|
11728
|
+
{
|
|
11729
|
+
type: "button",
|
|
11730
|
+
className: "butex-document2-widget__icon-btn butex-document2-widget__format-btn",
|
|
11731
|
+
title: messages.bold,
|
|
11732
|
+
"aria-label": messages.bold,
|
|
11733
|
+
"aria-pressed": activeTextStyles.bold === true,
|
|
11734
|
+
disabled: !canFormatText,
|
|
11735
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
11736
|
+
onClick: () => onToggleTextStyle?.("bold"),
|
|
11737
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "butex-document2-widget__format-icon butex-document2-widget__format-icon--bold", "aria-hidden": "true", children: "\u0646\u0635" })
|
|
11738
|
+
}
|
|
11739
|
+
),
|
|
11740
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
11741
|
+
"button",
|
|
11742
|
+
{
|
|
11743
|
+
type: "button",
|
|
11744
|
+
className: "butex-document2-widget__icon-btn butex-document2-widget__format-btn",
|
|
11745
|
+
title: messages.italic,
|
|
11746
|
+
"aria-label": messages.italic,
|
|
11747
|
+
"aria-pressed": activeTextStyles.italic === true,
|
|
11748
|
+
disabled: !canFormatText,
|
|
11749
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
11750
|
+
onClick: () => onToggleTextStyle?.("italic"),
|
|
11751
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "butex-document2-widget__format-icon butex-document2-widget__format-icon--italic", "aria-hidden": "true", children: "\u0646\u0635" })
|
|
11752
|
+
}
|
|
11753
|
+
),
|
|
11754
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
11755
|
+
"button",
|
|
11756
|
+
{
|
|
11757
|
+
type: "button",
|
|
11758
|
+
className: "butex-document2-widget__icon-btn butex-document2-widget__format-btn",
|
|
11759
|
+
title: messages.underline,
|
|
11760
|
+
"aria-label": messages.underline,
|
|
11761
|
+
"aria-pressed": activeTextStyles.underline === true,
|
|
11762
|
+
disabled: !canFormatText,
|
|
11763
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
11764
|
+
onClick: () => onToggleTextStyle?.("underline"),
|
|
11765
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "butex-document2-widget__format-icon butex-document2-widget__format-icon--underline", "aria-hidden": "true", children: "\u0646\u0635" })
|
|
11766
|
+
}
|
|
11767
|
+
)
|
|
11768
|
+
] }),
|
|
11498
11769
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "butex-document2-widget__toolbar-group", role: "group", "aria-label": messages.structure, children: [
|
|
11499
11770
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
11500
11771
|
"button",
|
|
@@ -11546,35 +11817,57 @@ function DocumentInsertToolbar({
|
|
|
11546
11817
|
)) }) : null
|
|
11547
11818
|
] })
|
|
11548
11819
|
] }),
|
|
11549
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.
|
|
11550
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.
|
|
11551
|
-
|
|
11552
|
-
|
|
11553
|
-
|
|
11554
|
-
"
|
|
11555
|
-
|
|
11556
|
-
|
|
11557
|
-
|
|
11558
|
-
|
|
11559
|
-
|
|
11560
|
-
|
|
11561
|
-
|
|
11562
|
-
|
|
11563
|
-
|
|
11564
|
-
|
|
11565
|
-
|
|
11566
|
-
|
|
11567
|
-
|
|
11568
|
-
|
|
11569
|
-
|
|
11570
|
-
|
|
11571
|
-
|
|
11572
|
-
|
|
11573
|
-
|
|
11574
|
-
|
|
11575
|
-
|
|
11576
|
-
|
|
11577
|
-
|
|
11820
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "butex-document2-widget__toolbar-group", role: "group", "aria-label": messages.citations, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "butex-document2-widget__references-menu", ref: referencesMenuRef, children: [
|
|
11821
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
11822
|
+
"button",
|
|
11823
|
+
{
|
|
11824
|
+
ref: referencesTriggerRef,
|
|
11825
|
+
type: "button",
|
|
11826
|
+
className: "butex-document2-widget__icon-btn butex-document2-widget__references-trigger",
|
|
11827
|
+
title: messages.citations,
|
|
11828
|
+
"aria-label": messages.citations,
|
|
11829
|
+
"aria-haspopup": "menu",
|
|
11830
|
+
"aria-expanded": referencesMenuOpen,
|
|
11831
|
+
onClick: () => setReferencesMenuOpen((open) => !open),
|
|
11832
|
+
children: [
|
|
11833
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "butex-document2-widget__icon-bibliography", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { viewBox: "0 0 16 16", width: "14", height: "14", focusable: "false", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { fill: "currentColor", d: "M2 2.2h4.2c.7 0 1.3.3 1.8.8.5-.5 1.1-.8 1.8-.8H14v10.6H9.8c-.6 0-1.1.3-1.4.8h-.8c-.3-.5-.8-.8-1.4-.8H2V2.2zm1.2 1.2v8.2h3c.4 0 .8.1 1.2.3V4.6c-.2-.7-.6-1.2-1.2-1.2h-3zm9.6 0h-3c-.6 0-1 .5-1.2 1.2v7.3c.4-.2.8-.3 1.2-.3h3V3.4z" }) }) }),
|
|
11834
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: messages.citations }),
|
|
11835
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "butex-document2-widget__menu-chevron", "aria-hidden": "true", children: "\u2304" })
|
|
11836
|
+
]
|
|
11837
|
+
}
|
|
11838
|
+
),
|
|
11839
|
+
referencesMenuOpen ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
11840
|
+
"div",
|
|
11841
|
+
{
|
|
11842
|
+
className: "butex-document2-widget__references-menu-options",
|
|
11843
|
+
role: "menu",
|
|
11844
|
+
"aria-label": messages.citations,
|
|
11845
|
+
onKeyDown: moveReferenceMenuFocus,
|
|
11846
|
+
children: [
|
|
11847
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", role: "menuitem", title: messages.insertCitation, onClick: () => runReferenceAction(onInsertCitation), children: [
|
|
11848
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { "aria-hidden": "true", children: "[]" }),
|
|
11849
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: messages.insertCitation })
|
|
11850
|
+
] }),
|
|
11851
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", role: "menuitem", title: messages.insertInternalRef, onClick: () => runReferenceAction(onInsertInternalRef), children: [
|
|
11852
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { "aria-hidden": "true", children: "\xA7" }),
|
|
11853
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: messages.insertInternalRef })
|
|
11854
|
+
] }),
|
|
11855
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", role: "menuitem", title: messages.insertBibliography, onClick: () => runReferenceAction(onInsertBibliography), children: [
|
|
11856
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "butex-document2-widget__icon-bibliography", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { viewBox: "0 0 16 16", width: "14", height: "14", focusable: "false", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { fill: "currentColor", d: "M2.2 2.4h7.2c.9 0 1.6.7 1.6 1.6v9.2c0 .5-.6.8-1 .5l-2.2-1.6H2.2c-.9 0-1.6-.7-1.6-1.6V4c0-.9.7-1.6 1.6-1.6zm0 1.2c-.2 0-.4.2-.4.4v6.5c0 .2.2.4.4.4h6.1l1.5 1.1V4c0-.2-.2-.4-.4-.4H2.2zM3.4 5.2h5.2v1H3.4zm0 2.1h4.2v1H3.4zm0 2.1h3.4v1H3.4zM11.4 4.1h2.2c.8 0 1.4.6 1.4 1.4v7.1c0 .4-.5.7-.8.4l-1.7-1.3h-1.1V4.1zm1.2 1.2v5.4l.7.5V5.5c0-.1-.1-.2-.2-.2h-.5z" }) }) }),
|
|
11857
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: messages.insertBibliography })
|
|
11858
|
+
] }),
|
|
11859
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", role: "menuitem", title: messages.manageReferences, onClick: () => runReferenceAction(onManageReferences), children: [
|
|
11860
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { "aria-hidden": "true", children: "\u2630" }),
|
|
11861
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: messages.manageReferences })
|
|
11862
|
+
] }),
|
|
11863
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", role: "menuitem", title: messages.manageLabels, onClick: () => runReferenceAction(onManageLabels), children: [
|
|
11864
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { "aria-hidden": "true", children: "\u2317" }),
|
|
11865
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: messages.manageLabels })
|
|
11866
|
+
] })
|
|
11867
|
+
]
|
|
11868
|
+
}
|
|
11869
|
+
) : null
|
|
11870
|
+
] }) }),
|
|
11578
11871
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "butex-document2-widget__toolbar-group", role: "group", "aria-label": messages.lists, children: [
|
|
11579
11872
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "butex-document2-widget__icon-btn", title: messages.bulletedList, "aria-label": messages.bulletedList, onClick: onAddList, children: "\u2022\u2261" }),
|
|
11580
11873
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "butex-document2-widget__icon-btn", title: messages.numberedList, "aria-label": messages.numberedList, onClick: onAddEnumerate, children: "1." })
|
|
@@ -11589,7 +11882,17 @@ var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
|
11589
11882
|
function PreviewInlines({ inlines, output }) {
|
|
11590
11883
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: inlines.map((inline, index) => {
|
|
11591
11884
|
if (inline.kind === "text") {
|
|
11592
|
-
|
|
11885
|
+
let content = /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: inline.text });
|
|
11886
|
+
if (inline.style?.bold) {
|
|
11887
|
+
content = /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { children: content });
|
|
11888
|
+
}
|
|
11889
|
+
if (inline.style?.italic) {
|
|
11890
|
+
content = /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("em", { children: content });
|
|
11891
|
+
}
|
|
11892
|
+
if (inline.style?.underline) {
|
|
11893
|
+
content = /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "butex-document2-widget__preview-underline", children: content });
|
|
11894
|
+
}
|
|
11895
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: content }, index);
|
|
11593
11896
|
}
|
|
11594
11897
|
if (inline.kind === "cite") {
|
|
11595
11898
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "butex-document2-widget__preview-cite", children: inline.label }, inline.id);
|
|
@@ -14785,7 +15088,7 @@ function RefPickerPopover({
|
|
|
14785
15088
|
|
|
14786
15089
|
// src/react-document2/editorFocus.ts
|
|
14787
15090
|
function createEmptyDocument2EditorFocus() {
|
|
14788
|
-
return { blockId: null, fieldId: null, textTokenId: null, caretOffset: 0 };
|
|
15091
|
+
return { blockId: null, fieldId: null, textTokenId: null, caretOffset: 0, selectionStart: 0, selectionEnd: 0 };
|
|
14789
15092
|
}
|
|
14790
15093
|
function findBlockIdForField(blocks, fieldId) {
|
|
14791
15094
|
for (const block of blocks) {
|
|
@@ -14993,6 +15296,89 @@ var DOCUMENT2_WIDGET_CSS = `
|
|
|
14993
15296
|
display: block;
|
|
14994
15297
|
}
|
|
14995
15298
|
|
|
15299
|
+
.butex-document2-widget__format-btn {
|
|
15300
|
+
font-family: "Amiri", "Noto Serif Arabic", Georgia, serif;
|
|
15301
|
+
min-width: 36px;
|
|
15302
|
+
}
|
|
15303
|
+
|
|
15304
|
+
.butex-document2-widget__format-icon {
|
|
15305
|
+
direction: rtl;
|
|
15306
|
+
display: inline-block;
|
|
15307
|
+
font-size: 0.84rem;
|
|
15308
|
+
font-weight: 500;
|
|
15309
|
+
}
|
|
15310
|
+
|
|
15311
|
+
.butex-document2-widget__format-icon--bold {
|
|
15312
|
+
font-weight: 900;
|
|
15313
|
+
}
|
|
15314
|
+
|
|
15315
|
+
.butex-document2-widget__format-icon--italic {
|
|
15316
|
+
font-style: italic;
|
|
15317
|
+
transform: skewX(-7deg);
|
|
15318
|
+
}
|
|
15319
|
+
|
|
15320
|
+
.butex-document2-widget__format-icon--underline {
|
|
15321
|
+
text-decoration: underline;
|
|
15322
|
+
text-underline-offset: 0.12em;
|
|
15323
|
+
}
|
|
15324
|
+
|
|
15325
|
+
.butex-document2-widget__format-underline,
|
|
15326
|
+
.butex-document2-widget__preview-underline {
|
|
15327
|
+
text-decoration: underline;
|
|
15328
|
+
text-underline-offset: 0.12em;
|
|
15329
|
+
}
|
|
15330
|
+
|
|
15331
|
+
.butex-document2-widget__references-menu {
|
|
15332
|
+
position: relative;
|
|
15333
|
+
}
|
|
15334
|
+
|
|
15335
|
+
.butex-document2-widget__references-trigger {
|
|
15336
|
+
gap: 5px;
|
|
15337
|
+
white-space: nowrap;
|
|
15338
|
+
}
|
|
15339
|
+
|
|
15340
|
+
.butex-document2-widget__menu-chevron {
|
|
15341
|
+
color: var(--butex-document2-muted);
|
|
15342
|
+
font-size: 0.8rem;
|
|
15343
|
+
}
|
|
15344
|
+
|
|
15345
|
+
.butex-document2-widget__references-menu-options {
|
|
15346
|
+
background: var(--butex-document2-panel);
|
|
15347
|
+
border: 1px solid var(--butex-document2-border);
|
|
15348
|
+
border-radius: 8px;
|
|
15349
|
+
box-shadow: 0 8px 24px color-mix(in srgb, var(--butex-document2-fg) 16%, transparent);
|
|
15350
|
+
display: grid;
|
|
15351
|
+
gap: 2px;
|
|
15352
|
+
inset-inline-start: 0;
|
|
15353
|
+
margin-top: 4px;
|
|
15354
|
+
min-width: max-content;
|
|
15355
|
+
padding: 4px;
|
|
15356
|
+
position: absolute;
|
|
15357
|
+
top: 100%;
|
|
15358
|
+
z-index: 30;
|
|
15359
|
+
}
|
|
15360
|
+
|
|
15361
|
+
.butex-document2-widget__references-menu-options button {
|
|
15362
|
+
align-items: center;
|
|
15363
|
+
background: transparent;
|
|
15364
|
+
border: 0;
|
|
15365
|
+
border-radius: 6px;
|
|
15366
|
+
color: var(--butex-document2-fg);
|
|
15367
|
+
cursor: pointer;
|
|
15368
|
+
display: grid;
|
|
15369
|
+
font: inherit;
|
|
15370
|
+
gap: 8px;
|
|
15371
|
+
grid-template-columns: 18px 1fr;
|
|
15372
|
+
padding: 7px 9px;
|
|
15373
|
+
text-align: start;
|
|
15374
|
+
}
|
|
15375
|
+
|
|
15376
|
+
.butex-document2-widget__references-menu-options button:hover,
|
|
15377
|
+
.butex-document2-widget__references-menu-options button:focus-visible {
|
|
15378
|
+
background: var(--butex-document2-accent-bg);
|
|
15379
|
+
outline: none;
|
|
15380
|
+
}
|
|
15381
|
+
|
|
14996
15382
|
.butex-document2-widget__float-meta {
|
|
14997
15383
|
display: grid;
|
|
14998
15384
|
gap: 8px;
|
|
@@ -15436,6 +15822,19 @@ var DOCUMENT2_WIDGET_CSS = `
|
|
|
15436
15822
|
border-color: color-mix(in srgb, var(--butex-document2-text-token-border) 55%, var(--butex-document2-accent));
|
|
15437
15823
|
}
|
|
15438
15824
|
|
|
15825
|
+
.butex-document2-widget__inline-text[data-bold="true"] {
|
|
15826
|
+
font-weight: 700;
|
|
15827
|
+
}
|
|
15828
|
+
|
|
15829
|
+
.butex-document2-widget__inline-text[data-italic="true"] {
|
|
15830
|
+
font-style: italic;
|
|
15831
|
+
}
|
|
15832
|
+
|
|
15833
|
+
.butex-document2-widget__inline-text[data-underline="true"] {
|
|
15834
|
+
text-decoration: underline;
|
|
15835
|
+
text-underline-offset: 0.12em;
|
|
15836
|
+
}
|
|
15837
|
+
|
|
15439
15838
|
.butex-document2-widget__inline-field input {
|
|
15440
15839
|
min-width: 12ch;
|
|
15441
15840
|
}
|
|
@@ -16453,6 +16852,50 @@ function topLevelBlockIdForField(document2, fieldId) {
|
|
|
16453
16852
|
function topLevelBlockIdForToken(document2, tokenId) {
|
|
16454
16853
|
return document2.blocks.find((block) => blockHasToken(block, tokenId))?.id ?? null;
|
|
16455
16854
|
}
|
|
16855
|
+
function findFormatTextToken(document2, focus) {
|
|
16856
|
+
if (!focus.fieldId || !focus.textTokenId || focus.selectionEnd <= focus.selectionStart) {
|
|
16857
|
+
return null;
|
|
16858
|
+
}
|
|
16859
|
+
function textTokenFromField(field) {
|
|
16860
|
+
if (field.id !== focus.fieldId) {
|
|
16861
|
+
return null;
|
|
16862
|
+
}
|
|
16863
|
+
const token = field.tokens.find((entry) => entry.id === focus.textTokenId && entry.kind === "text");
|
|
16864
|
+
return token ?? null;
|
|
16865
|
+
}
|
|
16866
|
+
function visit(blocks) {
|
|
16867
|
+
for (const block of blocks) {
|
|
16868
|
+
if (block.kind === "textBlock") {
|
|
16869
|
+
const token = block.command === "\\paragraph" ? textTokenFromField(block.field) : null;
|
|
16870
|
+
if (token) {
|
|
16871
|
+
return token;
|
|
16872
|
+
}
|
|
16873
|
+
} else if (block.kind === "list") {
|
|
16874
|
+
for (const item of block.items) {
|
|
16875
|
+
const itemToken = textTokenFromField(item.field);
|
|
16876
|
+
if (itemToken) {
|
|
16877
|
+
return itemToken;
|
|
16878
|
+
}
|
|
16879
|
+
const nestedToken = visit(item.blocks);
|
|
16880
|
+
if (nestedToken) {
|
|
16881
|
+
return nestedToken;
|
|
16882
|
+
}
|
|
16883
|
+
}
|
|
16884
|
+
} else if (block.kind === "table") {
|
|
16885
|
+
for (const row of block.rows) {
|
|
16886
|
+
for (const cell of row) {
|
|
16887
|
+
const token = textTokenFromField(cell);
|
|
16888
|
+
if (token) {
|
|
16889
|
+
return token;
|
|
16890
|
+
}
|
|
16891
|
+
}
|
|
16892
|
+
}
|
|
16893
|
+
}
|
|
16894
|
+
}
|
|
16895
|
+
return null;
|
|
16896
|
+
}
|
|
16897
|
+
return visit(document2.blocks);
|
|
16898
|
+
}
|
|
16456
16899
|
function formatDocument2Diagnostic(d, messages) {
|
|
16457
16900
|
if (d.message === "math_objects order mismatch") {
|
|
16458
16901
|
return `${messages.importOrderMismatch} ${messages.path}: ${d.path}`;
|
|
@@ -16571,6 +17014,9 @@ function ButexDocumentEditor2({
|
|
|
16571
17014
|
const selectionCount = blockSelection ? blockSelection.to - blockSelection.from + 1 : 0;
|
|
16572
17015
|
const canMoveSelectionUp = Boolean(blockSelection && blockSelection.from > 0);
|
|
16573
17016
|
const canMoveSelectionDown = Boolean(blockSelection && blockSelection.to < documentNode.blocks.length - 1);
|
|
17017
|
+
const formatTextToken = (0, import_react13.useMemo)(() => findFormatTextToken(documentNode, editorFocus), [documentNode, editorFocus]);
|
|
17018
|
+
const canFormatText = formatTextToken !== null;
|
|
17019
|
+
const activeTextStyles = formatTextToken?.style ?? {};
|
|
16574
17020
|
function clearBlockSelection() {
|
|
16575
17021
|
setBlockSelectionState(emptyBlockSelection());
|
|
16576
17022
|
}
|
|
@@ -16771,15 +17217,15 @@ function ButexDocumentEditor2({
|
|
|
16771
17217
|
root.addEventListener("keydown", onKeyDown);
|
|
16772
17218
|
return () => root.removeEventListener("keydown", onKeyDown);
|
|
16773
17219
|
}, [editorOpen]);
|
|
16774
|
-
function rememberFieldFocus(blockId, fieldId, textTokenId, caretOffset) {
|
|
17220
|
+
function rememberFieldFocus(blockId, fieldId, textTokenId, caretOffset, selectionStart, selectionEnd) {
|
|
16775
17221
|
openBlock(blockId);
|
|
16776
17222
|
clearBlockSelection();
|
|
16777
|
-
setEditorFocus({ blockId, fieldId, textTokenId, caretOffset });
|
|
17223
|
+
setEditorFocus({ blockId, fieldId, textTokenId, caretOffset, selectionStart, selectionEnd });
|
|
16778
17224
|
}
|
|
16779
17225
|
function rememberMathFocus(blockId, fieldId) {
|
|
16780
17226
|
openBlock(blockId);
|
|
16781
17227
|
clearBlockSelection();
|
|
16782
|
-
setEditorFocus({ blockId, fieldId, textTokenId: null, caretOffset: 0 });
|
|
17228
|
+
setEditorFocus({ blockId, fieldId, textTokenId: null, caretOffset: 0, selectionStart: 0, selectionEnd: 0 });
|
|
16783
17229
|
}
|
|
16784
17230
|
function rememberBlockFocus(blockId) {
|
|
16785
17231
|
openBlock(blockId);
|
|
@@ -17042,6 +17488,22 @@ function ButexDocumentEditor2({
|
|
|
17042
17488
|
function deleteRefToken(tokenId) {
|
|
17043
17489
|
applyDocument(removeRefTokenById(documentRef.current, tokenId), "immediate");
|
|
17044
17490
|
}
|
|
17491
|
+
function toggleInlineTextStyle(styleName) {
|
|
17492
|
+
if (!canFormatText || !editorFocus.fieldId || !editorFocus.textTokenId) {
|
|
17493
|
+
return;
|
|
17494
|
+
}
|
|
17495
|
+
applyDocument(
|
|
17496
|
+
toggleTextTokenStyle(
|
|
17497
|
+
documentRef.current,
|
|
17498
|
+
editorFocus.fieldId,
|
|
17499
|
+
editorFocus.textTokenId,
|
|
17500
|
+
editorFocus.selectionStart,
|
|
17501
|
+
editorFocus.selectionEnd,
|
|
17502
|
+
styleName
|
|
17503
|
+
),
|
|
17504
|
+
"immediate"
|
|
17505
|
+
);
|
|
17506
|
+
}
|
|
17045
17507
|
const showEditorPanel = !previewOnly && editorOpen;
|
|
17046
17508
|
const showPreviewPanel = previewOnly || previewOpen;
|
|
17047
17509
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
@@ -17064,8 +17526,11 @@ function ButexDocumentEditor2({
|
|
|
17064
17526
|
selectionCount,
|
|
17065
17527
|
canMoveSelectionUp,
|
|
17066
17528
|
canMoveSelectionDown,
|
|
17529
|
+
canFormatText,
|
|
17530
|
+
activeTextStyles,
|
|
17067
17531
|
onUndo: undoDocument,
|
|
17068
17532
|
onRedo: redoDocument,
|
|
17533
|
+
onToggleTextStyle: toggleInlineTextStyle,
|
|
17069
17534
|
onMoveSelectionUp: () => moveSelectedBlocks(-1),
|
|
17070
17535
|
onMoveSelectionDown: () => moveSelectedBlocks(1),
|
|
17071
17536
|
onDeleteSelection: deleteSelectedBlocks,
|