@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/README.md
CHANGED
|
@@ -253,7 +253,7 @@ const latex = document2Latex(documentNode);
|
|
|
253
253
|
const preview = document2Preview(documentNode, 'svg');
|
|
254
254
|
```
|
|
255
255
|
|
|
256
|
-
`document2Latex(doc)` emits a **complete Arabic XeLaTeX document** by default (preamble + `\begin{document}` + body + `\end{document}`). Pass `{ wrapDocument: false }` for body-only blocks. Optional `digitsMapping: 'arabicdigits' | 'digits'` controls eastern vs western digit font mapping in the preamble (default `'arabicdigits'`). Pass `{ twocolumn: true }` for `\documentclass[12pt,a4paper,notitlepage,twocolumn]{article}` (title block stays in-column; figures use `\columnwidth`). See [`examples/example-latex-export.tex`](examples/example-latex-export.tex) for a full sample (regenerated by the wrap vitest). Hosts can also call `getArabicXeLatexPreamble()` alone.
|
|
256
|
+
`document2Latex(doc)` emits a **complete Arabic XeLaTeX document** by default (preamble + `\begin{document}` + body + `\end{document}`). Pass `{ wrapDocument: false }` for body-only blocks. Paragraph blocks export as `\par` followed by the inline content, so prose, citations, and math are not wrapped inside `\paragraph{...}`. Optional `digitsMapping: 'arabicdigits' | 'digits'` controls eastern vs western digit font mapping in the preamble (default `'arabicdigits'`). Pass `{ twocolumn: true }` for `\documentclass[12pt,a4paper,notitlepage,twocolumn]{article}` (title block stays in-column; figures use `\columnwidth`). See [`examples/example-latex-export.tex`](examples/example-latex-export.tex) for a full sample (regenerated by the wrap vitest). Hosts can also call `getArabicXeLatexPreamble()` alone.
|
|
257
257
|
|
|
258
258
|
Figures and tables always export as centered `figure` / `table` floats. Optional caption/label fields (checkbox-driven in the editor) emit `\caption` / `\label`. Display math stays `\[…\]` unless an equation label is enabled, then export uses `\begin{equation}…\label{…}\end{equation}`. Internal cross-refs use `\ref` / `\eqref` tokens (separate from bibliography `\cite`).
|
|
259
259
|
|
|
@@ -343,7 +343,7 @@ Host apps still register BuTeX with MathJax before preview rendering. `uiLocale`
|
|
|
343
343
|
- Core editor classes (`.surface`, `.chain`, `.slot`, `.node`, `.scripts`, `.delim*`, etc.) are shipped from `src/editor/styles.ts`.
|
|
344
344
|
- Theme with **one namespace**, `--butex-*`, on `.butex-widget` (or an ancestor of the editor surface). Defaults are set on `ButexEditor`’s root; hosts override accents, borders, **`--butex-surface-bg` / `--butex-surface-fg`**, **`--butex-preview-bg` / `--butex-preview-fg`**, focus/slot/selection, scripts, optional **`--butex-dev-*`** / **`--butex-dev-inset-*`** when using `debug`, etc., without redefining structure classes.
|
|
345
345
|
- Document editor theming is scoped under `.butex-document-widget`. Override `--butex-document-*` variables on that root or an ancestor, especially `--butex-document-bg`, `--butex-document-fg`, `--butex-document-panel`, `--butex-document-border`, `--butex-document-accent`, `--butex-document-preview-bg`, `--butex-document-drawer-bg`, `--butex-document-input-bg`, `--butex-document-table-border`, `--butex-document-math-bg`, and `--butex-document-dev-bg`.
|
|
346
|
-
- Document editor v2 theming is scoped under `.butex-document2-widget`. Override `--butex-document2-*` variables on that root or an ancestor; defaults inherit from the existing `--butex-*` variables where practical, including accent, panel, border, preview, focus, danger/error, and debug colors. The embedded equation editor opens as a centered modal (backdrop + panel); its BuTeX chrome reads the same `--butex-document2-*` tokens via a scoped bridge, so hosts normally theme once on `.butex-document2-widget` without a second equation theme. The built-in editor uses a **sticky compact icon toolbar** (heading glyphs, inline `$…$` vs display `\[…\]` math buttons with tooltips, table size popover), **focus-aware block insertion** after the active block, **↑/↓ block reorder**, **math delete** (chip × and drawer button), **document undo/redo** (toolbar + Ctrl/⌘Z, Ctrl/⌘Shift+Z, Ctrl+Y) via AST snapshots, and theme-tinted block cards. Preview tables use fixed black cell borders; raw `\raw` blocks stay out of preview until dedicated rendering exists.
|
|
346
|
+
- Document editor v2 theming is scoped under `.butex-document2-widget`. Override `--butex-document2-*` variables on that root or an ancestor; defaults inherit from the existing `--butex-*` variables where practical, including accent, panel, border, preview, focus, danger/error, and debug colors. The embedded equation editor opens as a centered modal (backdrop + panel); its BuTeX chrome reads the same `--butex-document2-*` tokens via a scoped bridge, so hosts normally theme once on `.butex-document2-widget` without a second equation theme. The built-in editor uses a **sticky compact icon toolbar** (Arabic `نص` formatting icons, heading glyphs, inline `$…$` vs display `\[…\]` math buttons with tooltips, a labeled references menu, and a table size popover), **focus-aware block insertion** after the active block, **↑/↓ block reorder**, **math delete** (chip × and drawer button), **document undo/redo** (toolbar + Ctrl/⌘Z, Ctrl/⌘Shift+Z, Ctrl+Y) via AST snapshots, and theme-tinted block cards. Preview tables use fixed black cell borders; raw `\raw` blocks stay out of preview until dedicated rendering exists.
|
|
347
347
|
|
|
348
348
|
## Demo
|
|
349
349
|
|
package/dist/document2.d.mts
CHANGED
|
@@ -175,6 +175,7 @@ type Document2Json = {
|
|
|
175
175
|
type Document2BlockJson = {
|
|
176
176
|
command: string;
|
|
177
177
|
value?: string;
|
|
178
|
+
formats?: TextFormatSpan2Json[];
|
|
178
179
|
/** Stable host asset identity (e.g. S3 key / UUID); optional for \\includegraphics. */
|
|
179
180
|
asset_id?: string;
|
|
180
181
|
math_objects?: MathObject2Json[];
|
|
@@ -182,6 +183,7 @@ type Document2BlockJson = {
|
|
|
182
183
|
closing?: string;
|
|
183
184
|
items?: Document2ListItemJson[];
|
|
184
185
|
rows?: string[][];
|
|
186
|
+
cell_formats?: TextFormatSpan2Json[][][];
|
|
185
187
|
columns?: string;
|
|
186
188
|
caption?: string;
|
|
187
189
|
label?: string;
|
|
@@ -191,6 +193,7 @@ type Document2BlockJson = {
|
|
|
191
193
|
};
|
|
192
194
|
type Document2ListItemJson = {
|
|
193
195
|
value: string;
|
|
196
|
+
formats?: TextFormatSpan2Json[];
|
|
194
197
|
math_objects?: MathObject2Json[];
|
|
195
198
|
blocks?: Document2BlockJson[];
|
|
196
199
|
};
|
|
@@ -210,10 +213,23 @@ type Reference2 = {
|
|
|
210
213
|
/** Joins authors/title/venue/year in bibliography display and export. */
|
|
211
214
|
fieldSeparator: ReferenceFieldSeparator;
|
|
212
215
|
};
|
|
216
|
+
type TextStyle2 = {
|
|
217
|
+
bold?: true;
|
|
218
|
+
italic?: true;
|
|
219
|
+
underline?: true;
|
|
220
|
+
};
|
|
221
|
+
type TextFormatSpan2Json = {
|
|
222
|
+
start: number;
|
|
223
|
+
end: number;
|
|
224
|
+
bold?: boolean;
|
|
225
|
+
italic?: boolean;
|
|
226
|
+
underline?: boolean;
|
|
227
|
+
};
|
|
213
228
|
type TextToken2 = {
|
|
214
229
|
id: string;
|
|
215
230
|
kind: 'text';
|
|
216
231
|
text: string;
|
|
232
|
+
style?: TextStyle2;
|
|
217
233
|
};
|
|
218
234
|
type MathToken2 = {
|
|
219
235
|
id: string;
|
|
@@ -344,6 +360,7 @@ type DetectedInlineSpan2 = ({
|
|
|
344
360
|
type PreviewInline2 = {
|
|
345
361
|
kind: 'text';
|
|
346
362
|
text: string;
|
|
363
|
+
style?: TextStyle2;
|
|
347
364
|
} | {
|
|
348
365
|
kind: 'math';
|
|
349
366
|
id: string;
|
|
@@ -570,6 +587,7 @@ declare function insertDocument2BlockAfter(document: Document2Node, afterBlockId
|
|
|
570
587
|
declare function moveDocument2BlockById(document: Document2Node, blockId: string, direction: -1 | 1): Document2Node;
|
|
571
588
|
declare function moveDocument2BlockRange(document: Document2Node, from: number, to: number, direction: -1 | 1): Document2Node;
|
|
572
589
|
declare function removeDocument2BlockRange(document: Document2Node, from: number, to: number): Document2Node;
|
|
590
|
+
declare function toggleTextTokenStyle(document: Document2Node, fieldId: string, tokenId: string, selectionStart: number, selectionEnd: number, styleName: keyof TextStyle2): Document2Node;
|
|
573
591
|
declare function removeMathTokenById(document: Document2Node, tokenId: string): Document2Node;
|
|
574
592
|
declare function insertMathTokenAtCaret(document: Document2Node, fieldId: string, textTokenId: string | null, caretOffset: number, session: EditorSession, opening?: string, closing?: string, side?: EditorSide): Document2Node;
|
|
575
593
|
declare function insertMathToken(document: Document2Node, fieldId: string, insertIndex: number, session: EditorSession, opening?: string, closing?: string, side?: EditorSide): Document2Node;
|
|
@@ -699,7 +717,7 @@ declare function toggleBlockInSelection(state: BlockSelectionState, index: numbe
|
|
|
699
717
|
declare function extendBlockSelectionFromAnchor(state: BlockSelectionState, index: number, blockCount: number): BlockSelectionState;
|
|
700
718
|
declare function remapSelectionAfterRangeMove(selection: BlockSelectionRange, direction: -1 | 1): BlockSelectionRange;
|
|
701
719
|
|
|
702
|
-
declare function createInlineField2(value?: string, mathObjects?: MathObject2Json[], options?: ImportDocument2Options, path?: string, diagnostics?: Document2Diagnostic[]): InlineField2;
|
|
720
|
+
declare function createInlineField2(value?: string, mathObjects?: MathObject2Json[], options?: ImportDocument2Options, path?: string, diagnostics?: Document2Diagnostic[], formats?: TextFormatSpan2Json[]): InlineField2;
|
|
703
721
|
declare function fromDocumentJson2(json: unknown, options?: ImportDocument2Options): Document2Node;
|
|
704
722
|
declare function createEmptyDocument2(): Document2Node;
|
|
705
723
|
|
|
@@ -732,4 +750,4 @@ type Document2PreviewOptions = {
|
|
|
732
750
|
};
|
|
733
751
|
declare function document2Preview(document: Document2Node, output?: Document2MathOutput, equationSide?: EditorSide, previewOptions?: Document2PreviewOptions): Document2Preview;
|
|
734
752
|
|
|
735
|
-
export { type ArabicDigitsMapping, type ArabicXeLatexPreambleOptions, BUTEX_BASMALA, BUTEX_BASMALA_LINE1, BUTEX_BASMALA_LINE2, BUTEX_BASMALA_SALAWAT, BUTEX_CLOSING_HAMDALA, type BibliographyBlock2, type BlockSelectionRange, type BlockSelectionState, type CiteToken2, DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH, DEFAULT_HIJRI_DATE, DEFAULT_REFERENCE_FIELD_SEPARATOR, type Document2Block, type Document2BlockJson, type Document2Diagnostic, type Document2Direction, type Document2HijriDate, type Document2HistoryStacks, type Document2Json, type Document2KeyError, type Document2KeyNamespace, type Document2LabelEntry, type Document2LabelKind, type Document2LatexOptions, type Document2MathOutput, type Document2Meta, type Document2MetaProp, type Document2Node, type Document2Preview, type Document2PreviewOptions, type FloatMeta2, type FloatMetaPatch, type FormatCiteLabelOptions, type FormatFloatCaptionTitleOptions, HIJRI_MONTH_IDS, HIJRI_YEAR_MAX, HIJRI_YEAR_MIN, type HijriMonthId, type ImageBlock2, type ImportDocument2Options, type InlineField2, type InlineToken2, type ListBlock2, type MathIsland2, type MathObject2Json, type MathToken2, type PreviewBlock2, type PreviewInline2, type RawBlock2, type RefToken2, type Reference2, type Reference2Json, type ReferenceFieldSeparator, type TableBlock2, type TextBlock2, type TextToken2, absoluteHttpHref, addDocument2ImageBlock, addDocument2ListBlock, addDocument2ListItem, addDocument2Reference, addDocument2TableBlock, addDocument2TextBlock, applyFloatMetaPatch, arabicXeLatexPreambleCmd, arabicXeLatexPreambleFont, arabicXeLatexPreamblePkg, bibliographyEntryBody, bibliographyEntryLatex, butexBasmalaDisplayLatex, butexBasmalaDisplayTex, butexBasmalaTitlingPreamble, butexDiwaniDisplayLatex, butexDiwaniDisplayTex, butexInColumnMaketitleHook, citeTokenLatex, cloneDocument2Meta, cloneDocument2Node, collectDocument2Labels, createDocument2History, createEmptyArabicEquationSession, createEmptyDocument2, createEmptyEquationSession, createEmptyReference2, createInlineField2, defaultFloatMeta, detectInlineSpans2, detectMathSpans2, document2HasAbstract, document2HasMaketitle, document2HasTitleStack, document2HistoryCanRedo, document2HistoryCanUndo, document2KeyError, document2Latex, document2Preview, emptyBlockSelection, emptyDocument2Meta, ensureDocument2BibliographyBlock, extendBlockSelectionFromAnchor, fillDocument2MetaGaps, findFirstInlineField, formatBibliographyNumber, formatCiteLabel, formatFloatCaptionPreview, formatFloatCaptionTitle, formatHijriDate, formatRefLabel, fromDocumentJson2, getArabicXeLatexPreamble, hijriMonthLabel, inlineFieldLatex, insertCiteTokenAtCaret, insertDocument2BlockAfter, insertMathToken, insertMathTokenAtCaret, insertRefTokenAtCaret, isDuplicateDocument2Key, isValidDocument2Key, labelNumberMap, mathNodeFromArabicSession, mathNodeFromSession, mathSourceFromArabicSession, mathSourceFromSession, mathTokenSourceForSide, mathTokenToArabicEditorSession, mathTokenToEditorSession, mergeDocument2Meta, moveDocument2BlockById, moveDocument2BlockRange, moveDocument2Reference, normalizeBlockSelection, normalizeDocument2HijriDate, normalizeDocument2Key, normalizeDocument2Meta, normalizeReferenceFieldSeparator, parseCiteKeys, parseFloatMetaFromJson, parseRefKeys, pushDocument2Snapshot, refTokenLatex, referenceFromJson, referenceNumberMap, remapSelectionAfterRangeMove, removeCiteTokenById, removeDocument2BlockById, removeDocument2BlockRange, removeDocument2ListItem, removeDocument2Reference, removeMathTokenById, removeRefTokenById, replaceMathTokenFromSession, resolveCiteNumbers, restoreDocument2Redo, restoreDocument2Undo, setDocument2References, stripDisplayMathDelimiters, toggleBlockInSelection, updateCiteTokenKeys, updateDocument2ImageMeta, updateDocument2ImageValue, updateDocument2Meta, updateDocument2Reference, updateDocument2TableMeta, updateDocument2TextBlockCentered, updateMathTokenLabel, updateRefTokenKeys, updateTextToken };
|
|
753
|
+
export { type ArabicDigitsMapping, type ArabicXeLatexPreambleOptions, BUTEX_BASMALA, BUTEX_BASMALA_LINE1, BUTEX_BASMALA_LINE2, BUTEX_BASMALA_SALAWAT, BUTEX_CLOSING_HAMDALA, type BibliographyBlock2, type BlockSelectionRange, type BlockSelectionState, type CiteToken2, DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH, DEFAULT_HIJRI_DATE, DEFAULT_REFERENCE_FIELD_SEPARATOR, type Document2Block, type Document2BlockJson, type Document2Diagnostic, type Document2Direction, type Document2HijriDate, type Document2HistoryStacks, type Document2Json, type Document2KeyError, type Document2KeyNamespace, type Document2LabelEntry, type Document2LabelKind, type Document2LatexOptions, type Document2MathOutput, type Document2Meta, type Document2MetaProp, type Document2Node, type Document2Preview, type Document2PreviewOptions, type FloatMeta2, type FloatMetaPatch, type FormatCiteLabelOptions, type FormatFloatCaptionTitleOptions, HIJRI_MONTH_IDS, HIJRI_YEAR_MAX, HIJRI_YEAR_MIN, type HijriMonthId, type ImageBlock2, type ImportDocument2Options, type InlineField2, type InlineToken2, type ListBlock2, type MathIsland2, type MathObject2Json, type MathToken2, type PreviewBlock2, type PreviewInline2, type RawBlock2, type RefToken2, type Reference2, type Reference2Json, type ReferenceFieldSeparator, type TableBlock2, type TextBlock2, type TextFormatSpan2Json, type TextStyle2, type TextToken2, absoluteHttpHref, addDocument2ImageBlock, addDocument2ListBlock, addDocument2ListItem, addDocument2Reference, addDocument2TableBlock, addDocument2TextBlock, applyFloatMetaPatch, arabicXeLatexPreambleCmd, arabicXeLatexPreambleFont, arabicXeLatexPreamblePkg, bibliographyEntryBody, bibliographyEntryLatex, butexBasmalaDisplayLatex, butexBasmalaDisplayTex, butexBasmalaTitlingPreamble, butexDiwaniDisplayLatex, butexDiwaniDisplayTex, butexInColumnMaketitleHook, citeTokenLatex, cloneDocument2Meta, cloneDocument2Node, collectDocument2Labels, createDocument2History, createEmptyArabicEquationSession, createEmptyDocument2, createEmptyEquationSession, createEmptyReference2, createInlineField2, defaultFloatMeta, detectInlineSpans2, detectMathSpans2, document2HasAbstract, document2HasMaketitle, document2HasTitleStack, document2HistoryCanRedo, document2HistoryCanUndo, document2KeyError, document2Latex, document2Preview, emptyBlockSelection, emptyDocument2Meta, ensureDocument2BibliographyBlock, extendBlockSelectionFromAnchor, fillDocument2MetaGaps, findFirstInlineField, formatBibliographyNumber, formatCiteLabel, formatFloatCaptionPreview, formatFloatCaptionTitle, formatHijriDate, formatRefLabel, fromDocumentJson2, getArabicXeLatexPreamble, hijriMonthLabel, inlineFieldLatex, insertCiteTokenAtCaret, insertDocument2BlockAfter, insertMathToken, insertMathTokenAtCaret, insertRefTokenAtCaret, isDuplicateDocument2Key, isValidDocument2Key, labelNumberMap, mathNodeFromArabicSession, mathNodeFromSession, mathSourceFromArabicSession, mathSourceFromSession, mathTokenSourceForSide, mathTokenToArabicEditorSession, mathTokenToEditorSession, mergeDocument2Meta, moveDocument2BlockById, moveDocument2BlockRange, moveDocument2Reference, normalizeBlockSelection, normalizeDocument2HijriDate, normalizeDocument2Key, normalizeDocument2Meta, normalizeReferenceFieldSeparator, parseCiteKeys, parseFloatMetaFromJson, parseRefKeys, pushDocument2Snapshot, refTokenLatex, referenceFromJson, referenceNumberMap, remapSelectionAfterRangeMove, removeCiteTokenById, removeDocument2BlockById, removeDocument2BlockRange, removeDocument2ListItem, removeDocument2Reference, removeMathTokenById, removeRefTokenById, replaceMathTokenFromSession, resolveCiteNumbers, restoreDocument2Redo, restoreDocument2Undo, setDocument2References, stripDisplayMathDelimiters, toggleBlockInSelection, toggleTextTokenStyle, updateCiteTokenKeys, updateDocument2ImageMeta, updateDocument2ImageValue, updateDocument2Meta, updateDocument2Reference, updateDocument2TableMeta, updateDocument2TextBlockCentered, updateMathTokenLabel, updateRefTokenKeys, updateTextToken };
|
package/dist/document2.d.ts
CHANGED
|
@@ -175,6 +175,7 @@ type Document2Json = {
|
|
|
175
175
|
type Document2BlockJson = {
|
|
176
176
|
command: string;
|
|
177
177
|
value?: string;
|
|
178
|
+
formats?: TextFormatSpan2Json[];
|
|
178
179
|
/** Stable host asset identity (e.g. S3 key / UUID); optional for \\includegraphics. */
|
|
179
180
|
asset_id?: string;
|
|
180
181
|
math_objects?: MathObject2Json[];
|
|
@@ -182,6 +183,7 @@ type Document2BlockJson = {
|
|
|
182
183
|
closing?: string;
|
|
183
184
|
items?: Document2ListItemJson[];
|
|
184
185
|
rows?: string[][];
|
|
186
|
+
cell_formats?: TextFormatSpan2Json[][][];
|
|
185
187
|
columns?: string;
|
|
186
188
|
caption?: string;
|
|
187
189
|
label?: string;
|
|
@@ -191,6 +193,7 @@ type Document2BlockJson = {
|
|
|
191
193
|
};
|
|
192
194
|
type Document2ListItemJson = {
|
|
193
195
|
value: string;
|
|
196
|
+
formats?: TextFormatSpan2Json[];
|
|
194
197
|
math_objects?: MathObject2Json[];
|
|
195
198
|
blocks?: Document2BlockJson[];
|
|
196
199
|
};
|
|
@@ -210,10 +213,23 @@ type Reference2 = {
|
|
|
210
213
|
/** Joins authors/title/venue/year in bibliography display and export. */
|
|
211
214
|
fieldSeparator: ReferenceFieldSeparator;
|
|
212
215
|
};
|
|
216
|
+
type TextStyle2 = {
|
|
217
|
+
bold?: true;
|
|
218
|
+
italic?: true;
|
|
219
|
+
underline?: true;
|
|
220
|
+
};
|
|
221
|
+
type TextFormatSpan2Json = {
|
|
222
|
+
start: number;
|
|
223
|
+
end: number;
|
|
224
|
+
bold?: boolean;
|
|
225
|
+
italic?: boolean;
|
|
226
|
+
underline?: boolean;
|
|
227
|
+
};
|
|
213
228
|
type TextToken2 = {
|
|
214
229
|
id: string;
|
|
215
230
|
kind: 'text';
|
|
216
231
|
text: string;
|
|
232
|
+
style?: TextStyle2;
|
|
217
233
|
};
|
|
218
234
|
type MathToken2 = {
|
|
219
235
|
id: string;
|
|
@@ -344,6 +360,7 @@ type DetectedInlineSpan2 = ({
|
|
|
344
360
|
type PreviewInline2 = {
|
|
345
361
|
kind: 'text';
|
|
346
362
|
text: string;
|
|
363
|
+
style?: TextStyle2;
|
|
347
364
|
} | {
|
|
348
365
|
kind: 'math';
|
|
349
366
|
id: string;
|
|
@@ -570,6 +587,7 @@ declare function insertDocument2BlockAfter(document: Document2Node, afterBlockId
|
|
|
570
587
|
declare function moveDocument2BlockById(document: Document2Node, blockId: string, direction: -1 | 1): Document2Node;
|
|
571
588
|
declare function moveDocument2BlockRange(document: Document2Node, from: number, to: number, direction: -1 | 1): Document2Node;
|
|
572
589
|
declare function removeDocument2BlockRange(document: Document2Node, from: number, to: number): Document2Node;
|
|
590
|
+
declare function toggleTextTokenStyle(document: Document2Node, fieldId: string, tokenId: string, selectionStart: number, selectionEnd: number, styleName: keyof TextStyle2): Document2Node;
|
|
573
591
|
declare function removeMathTokenById(document: Document2Node, tokenId: string): Document2Node;
|
|
574
592
|
declare function insertMathTokenAtCaret(document: Document2Node, fieldId: string, textTokenId: string | null, caretOffset: number, session: EditorSession, opening?: string, closing?: string, side?: EditorSide): Document2Node;
|
|
575
593
|
declare function insertMathToken(document: Document2Node, fieldId: string, insertIndex: number, session: EditorSession, opening?: string, closing?: string, side?: EditorSide): Document2Node;
|
|
@@ -699,7 +717,7 @@ declare function toggleBlockInSelection(state: BlockSelectionState, index: numbe
|
|
|
699
717
|
declare function extendBlockSelectionFromAnchor(state: BlockSelectionState, index: number, blockCount: number): BlockSelectionState;
|
|
700
718
|
declare function remapSelectionAfterRangeMove(selection: BlockSelectionRange, direction: -1 | 1): BlockSelectionRange;
|
|
701
719
|
|
|
702
|
-
declare function createInlineField2(value?: string, mathObjects?: MathObject2Json[], options?: ImportDocument2Options, path?: string, diagnostics?: Document2Diagnostic[]): InlineField2;
|
|
720
|
+
declare function createInlineField2(value?: string, mathObjects?: MathObject2Json[], options?: ImportDocument2Options, path?: string, diagnostics?: Document2Diagnostic[], formats?: TextFormatSpan2Json[]): InlineField2;
|
|
703
721
|
declare function fromDocumentJson2(json: unknown, options?: ImportDocument2Options): Document2Node;
|
|
704
722
|
declare function createEmptyDocument2(): Document2Node;
|
|
705
723
|
|
|
@@ -732,4 +750,4 @@ type Document2PreviewOptions = {
|
|
|
732
750
|
};
|
|
733
751
|
declare function document2Preview(document: Document2Node, output?: Document2MathOutput, equationSide?: EditorSide, previewOptions?: Document2PreviewOptions): Document2Preview;
|
|
734
752
|
|
|
735
|
-
export { type ArabicDigitsMapping, type ArabicXeLatexPreambleOptions, BUTEX_BASMALA, BUTEX_BASMALA_LINE1, BUTEX_BASMALA_LINE2, BUTEX_BASMALA_SALAWAT, BUTEX_CLOSING_HAMDALA, type BibliographyBlock2, type BlockSelectionRange, type BlockSelectionState, type CiteToken2, DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH, DEFAULT_HIJRI_DATE, DEFAULT_REFERENCE_FIELD_SEPARATOR, type Document2Block, type Document2BlockJson, type Document2Diagnostic, type Document2Direction, type Document2HijriDate, type Document2HistoryStacks, type Document2Json, type Document2KeyError, type Document2KeyNamespace, type Document2LabelEntry, type Document2LabelKind, type Document2LatexOptions, type Document2MathOutput, type Document2Meta, type Document2MetaProp, type Document2Node, type Document2Preview, type Document2PreviewOptions, type FloatMeta2, type FloatMetaPatch, type FormatCiteLabelOptions, type FormatFloatCaptionTitleOptions, HIJRI_MONTH_IDS, HIJRI_YEAR_MAX, HIJRI_YEAR_MIN, type HijriMonthId, type ImageBlock2, type ImportDocument2Options, type InlineField2, type InlineToken2, type ListBlock2, type MathIsland2, type MathObject2Json, type MathToken2, type PreviewBlock2, type PreviewInline2, type RawBlock2, type RefToken2, type Reference2, type Reference2Json, type ReferenceFieldSeparator, type TableBlock2, type TextBlock2, type TextToken2, absoluteHttpHref, addDocument2ImageBlock, addDocument2ListBlock, addDocument2ListItem, addDocument2Reference, addDocument2TableBlock, addDocument2TextBlock, applyFloatMetaPatch, arabicXeLatexPreambleCmd, arabicXeLatexPreambleFont, arabicXeLatexPreamblePkg, bibliographyEntryBody, bibliographyEntryLatex, butexBasmalaDisplayLatex, butexBasmalaDisplayTex, butexBasmalaTitlingPreamble, butexDiwaniDisplayLatex, butexDiwaniDisplayTex, butexInColumnMaketitleHook, citeTokenLatex, cloneDocument2Meta, cloneDocument2Node, collectDocument2Labels, createDocument2History, createEmptyArabicEquationSession, createEmptyDocument2, createEmptyEquationSession, createEmptyReference2, createInlineField2, defaultFloatMeta, detectInlineSpans2, detectMathSpans2, document2HasAbstract, document2HasMaketitle, document2HasTitleStack, document2HistoryCanRedo, document2HistoryCanUndo, document2KeyError, document2Latex, document2Preview, emptyBlockSelection, emptyDocument2Meta, ensureDocument2BibliographyBlock, extendBlockSelectionFromAnchor, fillDocument2MetaGaps, findFirstInlineField, formatBibliographyNumber, formatCiteLabel, formatFloatCaptionPreview, formatFloatCaptionTitle, formatHijriDate, formatRefLabel, fromDocumentJson2, getArabicXeLatexPreamble, hijriMonthLabel, inlineFieldLatex, insertCiteTokenAtCaret, insertDocument2BlockAfter, insertMathToken, insertMathTokenAtCaret, insertRefTokenAtCaret, isDuplicateDocument2Key, isValidDocument2Key, labelNumberMap, mathNodeFromArabicSession, mathNodeFromSession, mathSourceFromArabicSession, mathSourceFromSession, mathTokenSourceForSide, mathTokenToArabicEditorSession, mathTokenToEditorSession, mergeDocument2Meta, moveDocument2BlockById, moveDocument2BlockRange, moveDocument2Reference, normalizeBlockSelection, normalizeDocument2HijriDate, normalizeDocument2Key, normalizeDocument2Meta, normalizeReferenceFieldSeparator, parseCiteKeys, parseFloatMetaFromJson, parseRefKeys, pushDocument2Snapshot, refTokenLatex, referenceFromJson, referenceNumberMap, remapSelectionAfterRangeMove, removeCiteTokenById, removeDocument2BlockById, removeDocument2BlockRange, removeDocument2ListItem, removeDocument2Reference, removeMathTokenById, removeRefTokenById, replaceMathTokenFromSession, resolveCiteNumbers, restoreDocument2Redo, restoreDocument2Undo, setDocument2References, stripDisplayMathDelimiters, toggleBlockInSelection, updateCiteTokenKeys, updateDocument2ImageMeta, updateDocument2ImageValue, updateDocument2Meta, updateDocument2Reference, updateDocument2TableMeta, updateDocument2TextBlockCentered, updateMathTokenLabel, updateRefTokenKeys, updateTextToken };
|
|
753
|
+
export { type ArabicDigitsMapping, type ArabicXeLatexPreambleOptions, BUTEX_BASMALA, BUTEX_BASMALA_LINE1, BUTEX_BASMALA_LINE2, BUTEX_BASMALA_SALAWAT, BUTEX_CLOSING_HAMDALA, type BibliographyBlock2, type BlockSelectionRange, type BlockSelectionState, type CiteToken2, DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH, DEFAULT_HIJRI_DATE, DEFAULT_REFERENCE_FIELD_SEPARATOR, type Document2Block, type Document2BlockJson, type Document2Diagnostic, type Document2Direction, type Document2HijriDate, type Document2HistoryStacks, type Document2Json, type Document2KeyError, type Document2KeyNamespace, type Document2LabelEntry, type Document2LabelKind, type Document2LatexOptions, type Document2MathOutput, type Document2Meta, type Document2MetaProp, type Document2Node, type Document2Preview, type Document2PreviewOptions, type FloatMeta2, type FloatMetaPatch, type FormatCiteLabelOptions, type FormatFloatCaptionTitleOptions, HIJRI_MONTH_IDS, HIJRI_YEAR_MAX, HIJRI_YEAR_MIN, type HijriMonthId, type ImageBlock2, type ImportDocument2Options, type InlineField2, type InlineToken2, type ListBlock2, type MathIsland2, type MathObject2Json, type MathToken2, type PreviewBlock2, type PreviewInline2, type RawBlock2, type RefToken2, type Reference2, type Reference2Json, type ReferenceFieldSeparator, type TableBlock2, type TextBlock2, type TextFormatSpan2Json, type TextStyle2, type TextToken2, absoluteHttpHref, addDocument2ImageBlock, addDocument2ListBlock, addDocument2ListItem, addDocument2Reference, addDocument2TableBlock, addDocument2TextBlock, applyFloatMetaPatch, arabicXeLatexPreambleCmd, arabicXeLatexPreambleFont, arabicXeLatexPreamblePkg, bibliographyEntryBody, bibliographyEntryLatex, butexBasmalaDisplayLatex, butexBasmalaDisplayTex, butexBasmalaTitlingPreamble, butexDiwaniDisplayLatex, butexDiwaniDisplayTex, butexInColumnMaketitleHook, citeTokenLatex, cloneDocument2Meta, cloneDocument2Node, collectDocument2Labels, createDocument2History, createEmptyArabicEquationSession, createEmptyDocument2, createEmptyEquationSession, createEmptyReference2, createInlineField2, defaultFloatMeta, detectInlineSpans2, detectMathSpans2, document2HasAbstract, document2HasMaketitle, document2HasTitleStack, document2HistoryCanRedo, document2HistoryCanUndo, document2KeyError, document2Latex, document2Preview, emptyBlockSelection, emptyDocument2Meta, ensureDocument2BibliographyBlock, extendBlockSelectionFromAnchor, fillDocument2MetaGaps, findFirstInlineField, formatBibliographyNumber, formatCiteLabel, formatFloatCaptionPreview, formatFloatCaptionTitle, formatHijriDate, formatRefLabel, fromDocumentJson2, getArabicXeLatexPreamble, hijriMonthLabel, inlineFieldLatex, insertCiteTokenAtCaret, insertDocument2BlockAfter, insertMathToken, insertMathTokenAtCaret, insertRefTokenAtCaret, isDuplicateDocument2Key, isValidDocument2Key, labelNumberMap, mathNodeFromArabicSession, mathNodeFromSession, mathSourceFromArabicSession, mathSourceFromSession, mathTokenSourceForSide, mathTokenToArabicEditorSession, mathTokenToEditorSession, mergeDocument2Meta, moveDocument2BlockById, moveDocument2BlockRange, moveDocument2Reference, normalizeBlockSelection, normalizeDocument2HijriDate, normalizeDocument2Key, normalizeDocument2Meta, normalizeReferenceFieldSeparator, parseCiteKeys, parseFloatMetaFromJson, parseRefKeys, pushDocument2Snapshot, refTokenLatex, referenceFromJson, referenceNumberMap, remapSelectionAfterRangeMove, removeCiteTokenById, removeDocument2BlockById, removeDocument2BlockRange, removeDocument2ListItem, removeDocument2Reference, removeMathTokenById, removeRefTokenById, replaceMathTokenFromSession, resolveCiteNumbers, restoreDocument2Redo, restoreDocument2Undo, setDocument2References, stripDisplayMathDelimiters, toggleBlockInSelection, toggleTextTokenStyle, updateCiteTokenKeys, updateDocument2ImageMeta, updateDocument2ImageValue, updateDocument2Meta, updateDocument2Reference, updateDocument2TableMeta, updateDocument2TextBlockCentered, updateMathTokenLabel, updateRefTokenKeys, updateTextToken };
|
package/dist/document2.js
CHANGED
|
@@ -133,6 +133,7 @@ __export(document2_exports, {
|
|
|
133
133
|
setDocument2References: () => setDocument2References,
|
|
134
134
|
stripDisplayMathDelimiters: () => stripDisplayMathDelimiters,
|
|
135
135
|
toggleBlockInSelection: () => toggleBlockInSelection,
|
|
136
|
+
toggleTextTokenStyle: () => toggleTextTokenStyle,
|
|
136
137
|
updateCiteTokenKeys: () => updateCiteTokenKeys,
|
|
137
138
|
updateDocument2ImageMeta: () => updateDocument2ImageMeta,
|
|
138
139
|
updateDocument2ImageValue: () => updateDocument2ImageValue,
|
|
@@ -1281,7 +1282,7 @@ function parseReferences(json) {
|
|
|
1281
1282
|
}
|
|
1282
1283
|
return references;
|
|
1283
1284
|
}
|
|
1284
|
-
function createInlineField2(value = "", mathObjects = [], options = {}, path = "$", diagnostics = []) {
|
|
1285
|
+
function createInlineField2(value = "", mathObjects = [], options = {}, path = "$", diagnostics = [], formats = []) {
|
|
1285
1286
|
const mode = options.mode ?? "english";
|
|
1286
1287
|
const spans = detectInlineSpans2(value);
|
|
1287
1288
|
const mathSpans = spans.filter((span) => span.kind === "math");
|
|
@@ -1293,7 +1294,7 @@ function createInlineField2(value = "", mathObjects = [], options = {}, path = "
|
|
|
1293
1294
|
}
|
|
1294
1295
|
for (const span of spans) {
|
|
1295
1296
|
if (span.start > index) {
|
|
1296
|
-
tokens
|
|
1297
|
+
pushFormattedTextTokens(tokens, value.slice(index, span.start), index, formats);
|
|
1297
1298
|
}
|
|
1298
1299
|
if (span.kind === "cite") {
|
|
1299
1300
|
tokens.push({
|
|
@@ -1349,9 +1350,81 @@ function createInlineField2(value = "", mathObjects = [], options = {}, path = "
|
|
|
1349
1350
|
index = span.end;
|
|
1350
1351
|
}
|
|
1351
1352
|
if (index < value.length || tokens.length === 0) {
|
|
1352
|
-
tokens
|
|
1353
|
+
pushFormattedTextTokens(tokens, value.slice(index), index, formats);
|
|
1354
|
+
}
|
|
1355
|
+
return { id: document2Id("field"), tokens: compactTextTokens(tokens) };
|
|
1356
|
+
}
|
|
1357
|
+
function styleFromFormat(format) {
|
|
1358
|
+
const style = {};
|
|
1359
|
+
if (format.bold === true) {
|
|
1360
|
+
style.bold = true;
|
|
1361
|
+
}
|
|
1362
|
+
if (format.italic === true) {
|
|
1363
|
+
style.italic = true;
|
|
1364
|
+
}
|
|
1365
|
+
if (format.underline === true) {
|
|
1366
|
+
style.underline = true;
|
|
1367
|
+
}
|
|
1368
|
+
return style.bold || style.italic || style.underline ? style : null;
|
|
1369
|
+
}
|
|
1370
|
+
function mergeTextStyle(base, added) {
|
|
1371
|
+
return {
|
|
1372
|
+
...base?.bold ? { bold: true } : {},
|
|
1373
|
+
...base?.italic ? { italic: true } : {},
|
|
1374
|
+
...base?.underline ? { underline: true } : {},
|
|
1375
|
+
...added.bold ? { bold: true } : {},
|
|
1376
|
+
...added.italic ? { italic: true } : {},
|
|
1377
|
+
...added.underline ? { underline: true } : {}
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
function textStylesEqual(a, b) {
|
|
1381
|
+
return Boolean(a?.bold) === Boolean(b?.bold) && Boolean(a?.italic) === Boolean(b?.italic) && Boolean(a?.underline) === Boolean(b?.underline);
|
|
1382
|
+
}
|
|
1383
|
+
function compactTextTokens(tokens) {
|
|
1384
|
+
const compacted = [];
|
|
1385
|
+
for (const token of tokens) {
|
|
1386
|
+
const previous = compacted[compacted.length - 1];
|
|
1387
|
+
if (previous?.kind === "text" && token.kind === "text" && textStylesEqual(previous.style, token.style)) {
|
|
1388
|
+
previous.text += token.text;
|
|
1389
|
+
} else {
|
|
1390
|
+
compacted.push(token);
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
return compacted;
|
|
1394
|
+
}
|
|
1395
|
+
function styleKey(style) {
|
|
1396
|
+
return `${style?.bold ? "b" : ""}${style?.italic ? "i" : ""}${style?.underline ? "u" : ""}`;
|
|
1397
|
+
}
|
|
1398
|
+
function pushFormattedTextTokens(tokens, text, sourceStart, formats) {
|
|
1399
|
+
if (text.length === 0) {
|
|
1400
|
+
tokens.push({ id: document2Id("text"), kind: "text", text });
|
|
1401
|
+
return;
|
|
1402
|
+
}
|
|
1403
|
+
const styles = Array.from({ length: text.length });
|
|
1404
|
+
for (const format of formats) {
|
|
1405
|
+
const style = styleFromFormat(format);
|
|
1406
|
+
if (!style || !Number.isFinite(format.start) || !Number.isFinite(format.end)) {
|
|
1407
|
+
continue;
|
|
1408
|
+
}
|
|
1409
|
+
const start = Math.max(0, Math.min(text.length, Math.trunc(format.start) - sourceStart));
|
|
1410
|
+
const end = Math.max(0, Math.min(text.length, Math.trunc(format.end) - sourceStart));
|
|
1411
|
+
if (end <= start) {
|
|
1412
|
+
continue;
|
|
1413
|
+
}
|
|
1414
|
+
for (let index = start; index < end; index += 1) {
|
|
1415
|
+
styles[index] = mergeTextStyle(styles[index], style);
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
let chunkStart = 0;
|
|
1419
|
+
for (let index = 1; index <= text.length; index += 1) {
|
|
1420
|
+
if (index < text.length && styleKey(styles[index]) === styleKey(styles[chunkStart])) {
|
|
1421
|
+
continue;
|
|
1422
|
+
}
|
|
1423
|
+
const chunk = text.slice(chunkStart, index);
|
|
1424
|
+
const style = styles[chunkStart];
|
|
1425
|
+
tokens.push({ id: document2Id("text"), kind: "text", text: chunk, ...style ? { style } : {} });
|
|
1426
|
+
chunkStart = index;
|
|
1353
1427
|
}
|
|
1354
|
-
return { id: document2Id("field"), tokens };
|
|
1355
1428
|
}
|
|
1356
1429
|
function closingForList(command) {
|
|
1357
1430
|
return command === "\\begin{itemize}" ? "\\end{itemize}" : "\\end{enumerate}";
|
|
@@ -1362,7 +1435,7 @@ function parseTextBlock(json, options, path, diagnostics) {
|
|
|
1362
1435
|
id: document2Id("block"),
|
|
1363
1436
|
kind: "textBlock",
|
|
1364
1437
|
command: json.command,
|
|
1365
|
-
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics),
|
|
1438
|
+
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics, json.command === "\\paragraph" ? json.formats ?? [] : []),
|
|
1366
1439
|
...json.centered === true ? { centered: true } : {}
|
|
1367
1440
|
};
|
|
1368
1441
|
}
|
|
@@ -1371,7 +1444,7 @@ function parseListItem(json, options, path, diagnostics) {
|
|
|
1371
1444
|
const blocksJson = Array.isArray(json.blocks) ? json.blocks : [];
|
|
1372
1445
|
return {
|
|
1373
1446
|
id: document2Id("item"),
|
|
1374
|
-
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics),
|
|
1447
|
+
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics, json.formats ?? []),
|
|
1375
1448
|
blocks: blocksJson.map((block, index) => parseBlock(asBlockJson(block), options, `${path}.blocks[${String(index)}]`, diagnostics))
|
|
1376
1449
|
};
|
|
1377
1450
|
}
|
|
@@ -1404,7 +1477,8 @@ function parseTableBlock(json, options, path, diagnostics) {
|
|
|
1404
1477
|
const spanCount = detectMathSpans2(value).length;
|
|
1405
1478
|
const cellMathObjects = mathObjects.slice(mathObjectIndex, mathObjectIndex + spanCount);
|
|
1406
1479
|
mathObjectIndex += spanCount;
|
|
1407
|
-
|
|
1480
|
+
const cellFormats = json.cell_formats?.[rowIndex]?.[columnIndex] ?? [];
|
|
1481
|
+
return createInlineField2(value, cellMathObjects, options, `${path}.rows[${String(rowIndex)}][${String(columnIndex)}]`, diagnostics, cellFormats);
|
|
1408
1482
|
});
|
|
1409
1483
|
});
|
|
1410
1484
|
if (mathObjects.length > 0 && mathObjects.length !== mathObjectIndex) {
|
|
@@ -4444,6 +4518,79 @@ function normalizeFieldTokens(tokens) {
|
|
|
4444
4518
|
}
|
|
4445
4519
|
return tokens;
|
|
4446
4520
|
}
|
|
4521
|
+
function textStylesEqual2(a, b) {
|
|
4522
|
+
return Boolean(a?.bold) === Boolean(b?.bold) && Boolean(a?.italic) === Boolean(b?.italic) && Boolean(a?.underline) === Boolean(b?.underline);
|
|
4523
|
+
}
|
|
4524
|
+
function compactAdjacentTextTokens(tokens) {
|
|
4525
|
+
const compacted = [];
|
|
4526
|
+
for (const token of tokens) {
|
|
4527
|
+
const previous = compacted[compacted.length - 1];
|
|
4528
|
+
if (previous?.kind === "text" && token.kind === "text" && textStylesEqual2(previous.style, token.style)) {
|
|
4529
|
+
previous.text += token.text;
|
|
4530
|
+
} else {
|
|
4531
|
+
compacted.push(token);
|
|
4532
|
+
}
|
|
4533
|
+
}
|
|
4534
|
+
return normalizeFieldTokens(compacted);
|
|
4535
|
+
}
|
|
4536
|
+
function withoutEmptyStyle(style) {
|
|
4537
|
+
const next = {};
|
|
4538
|
+
if (style.bold) {
|
|
4539
|
+
next.bold = true;
|
|
4540
|
+
}
|
|
4541
|
+
if (style.italic) {
|
|
4542
|
+
next.italic = true;
|
|
4543
|
+
}
|
|
4544
|
+
if (style.underline) {
|
|
4545
|
+
next.underline = true;
|
|
4546
|
+
}
|
|
4547
|
+
return next.bold || next.italic || next.underline ? next : void 0;
|
|
4548
|
+
}
|
|
4549
|
+
function textTokenPart(text, style, id = document2Id("text")) {
|
|
4550
|
+
return { id, kind: "text", text, ...style ? { style } : {} };
|
|
4551
|
+
}
|
|
4552
|
+
function toggleTextTokenStyle(document2, fieldId, tokenId, selectionStart, selectionEnd, styleName) {
|
|
4553
|
+
if (selectionEnd <= selectionStart) {
|
|
4554
|
+
return document2;
|
|
4555
|
+
}
|
|
4556
|
+
const next = cloneDocument(document2);
|
|
4557
|
+
visitFields(next.blocks, (field) => {
|
|
4558
|
+
if (field.id !== fieldId) {
|
|
4559
|
+
return false;
|
|
4560
|
+
}
|
|
4561
|
+
const tokenIndex = field.tokens.findIndex((entry) => entry.id === tokenId && entry.kind === "text");
|
|
4562
|
+
if (tokenIndex < 0) {
|
|
4563
|
+
return true;
|
|
4564
|
+
}
|
|
4565
|
+
const token = field.tokens[tokenIndex];
|
|
4566
|
+
const start = Math.max(0, Math.min(token.text.length, selectionStart));
|
|
4567
|
+
const end = Math.max(0, Math.min(token.text.length, selectionEnd));
|
|
4568
|
+
if (end <= start) {
|
|
4569
|
+
return true;
|
|
4570
|
+
}
|
|
4571
|
+
const selectedStyle = token.style ?? {};
|
|
4572
|
+
const enabled = selectedStyle[styleName] === true;
|
|
4573
|
+
const nextStyle = withoutEmptyStyle({ ...selectedStyle, [styleName]: enabled ? void 0 : true });
|
|
4574
|
+
const parts = [];
|
|
4575
|
+
const before = token.text.slice(0, start);
|
|
4576
|
+
const selected = token.text.slice(start, end);
|
|
4577
|
+
const after = token.text.slice(end);
|
|
4578
|
+
if (before.length > 0) {
|
|
4579
|
+
parts.push(textTokenPart(before, token.style, token.id));
|
|
4580
|
+
}
|
|
4581
|
+
parts.push(textTokenPart(selected, nextStyle, before.length > 0 ? document2Id("text") : token.id));
|
|
4582
|
+
if (after.length > 0) {
|
|
4583
|
+
parts.push(textTokenPart(after, token.style));
|
|
4584
|
+
}
|
|
4585
|
+
field.tokens = compactAdjacentTextTokens([
|
|
4586
|
+
...field.tokens.slice(0, tokenIndex),
|
|
4587
|
+
...parts,
|
|
4588
|
+
...field.tokens.slice(tokenIndex + 1)
|
|
4589
|
+
]);
|
|
4590
|
+
return true;
|
|
4591
|
+
});
|
|
4592
|
+
return next;
|
|
4593
|
+
}
|
|
4447
4594
|
function stitchTextAroundRemovedToken(tokens, index) {
|
|
4448
4595
|
const before = tokens[index - 1];
|
|
4449
4596
|
const after = tokens[index + 1];
|
|
@@ -4471,8 +4618,8 @@ function removeMathTokenById(document2, tokenId) {
|
|
|
4471
4618
|
function splitTextTokenAt(token, offset) {
|
|
4472
4619
|
const safeOffset = Math.max(0, Math.min(offset, token.text.length));
|
|
4473
4620
|
return [
|
|
4474
|
-
{ id: token.id, kind: "text", text: token.text.slice(0, safeOffset) },
|
|
4475
|
-
{ id: document2Id("text"), kind: "text", text: token.text.slice(safeOffset) }
|
|
4621
|
+
{ id: token.id, kind: "text", text: token.text.slice(0, safeOffset), ...token.style ? { style: token.style } : {} },
|
|
4622
|
+
{ id: document2Id("text"), kind: "text", text: token.text.slice(safeOffset), ...token.style ? { style: token.style } : {} }
|
|
4476
4623
|
];
|
|
4477
4624
|
}
|
|
4478
4625
|
function insertMathTokenAtCaret(document2, fieldId, textTokenId, caretOffset, session, opening = "$", closing = "$", side = "arabic") {
|
|
@@ -5214,9 +5361,22 @@ function mathBodyLatex(token) {
|
|
|
5214
5361
|
const rendered = renderMathNodeLatex(token.math);
|
|
5215
5362
|
return stripDisplayMathDelimiters(rendered);
|
|
5216
5363
|
}
|
|
5364
|
+
function styledTextLatex(text, style) {
|
|
5365
|
+
let output = text;
|
|
5366
|
+
if (style?.bold) {
|
|
5367
|
+
output = `\\textbf{${output}}`;
|
|
5368
|
+
}
|
|
5369
|
+
if (style?.italic) {
|
|
5370
|
+
output = `\\textit{${output}}`;
|
|
5371
|
+
}
|
|
5372
|
+
if (style?.underline) {
|
|
5373
|
+
output = `\\underline{${output}}`;
|
|
5374
|
+
}
|
|
5375
|
+
return output;
|
|
5376
|
+
}
|
|
5217
5377
|
function tokenLatex(token) {
|
|
5218
5378
|
if (token.kind === "text") {
|
|
5219
|
-
return token.text;
|
|
5379
|
+
return styledTextLatex(token.text, token.style);
|
|
5220
5380
|
}
|
|
5221
5381
|
if (token.kind === "cite") {
|
|
5222
5382
|
return citeTokenLatex(token.keys);
|
|
@@ -5240,7 +5400,9 @@ function inlineFieldLatex(field) {
|
|
|
5240
5400
|
return field.tokens.map((token) => tokenLatex(token)).join("");
|
|
5241
5401
|
}
|
|
5242
5402
|
function textBlockLatex(block) {
|
|
5243
|
-
const
|
|
5403
|
+
const content = inlineFieldLatex(block.field);
|
|
5404
|
+
const body = block.command === "\\paragraph" ? `\\par
|
|
5405
|
+
${content}` : `${block.command}{${content}}`;
|
|
5244
5406
|
if (block.command === "\\paragraph" && block.centered) {
|
|
5245
5407
|
return `\\begin{center}
|
|
5246
5408
|
${body}
|
|
@@ -5492,7 +5654,7 @@ function mathTex(token, equationSide) {
|
|
|
5492
5654
|
function previewInlines(field, islands, output, equationSide, document2, previewOptions) {
|
|
5493
5655
|
return field.tokens.map((token) => {
|
|
5494
5656
|
if (token.kind === "text") {
|
|
5495
|
-
return { kind: "text", text: token.text };
|
|
5657
|
+
return { kind: "text", text: token.text, ...token.style ? { style: token.style } : {} };
|
|
5496
5658
|
}
|
|
5497
5659
|
if (token.kind === "cite") {
|
|
5498
5660
|
return {
|
|
@@ -5774,6 +5936,7 @@ function document2Preview(document2, output = "svg", equationSide = "arabic", pr
|
|
|
5774
5936
|
setDocument2References,
|
|
5775
5937
|
stripDisplayMathDelimiters,
|
|
5776
5938
|
toggleBlockInSelection,
|
|
5939
|
+
toggleTextTokenStyle,
|
|
5777
5940
|
updateCiteTokenKeys,
|
|
5778
5941
|
updateDocument2ImageMeta,
|
|
5779
5942
|
updateDocument2ImageValue,
|