Skip to content

Commit

Permalink
fix: fixed #2535 Blackboard style incorrectly serialized when input l…
Browse files Browse the repository at this point in the history
…atex using physical keyboard
  • Loading branch information
arnog committed Nov 16, 2024
1 parent 3cc8a0a commit 283b3f6
Show file tree
Hide file tree
Showing 41 changed files with 393 additions and 374 deletions.
62 changes: 35 additions & 27 deletions src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -3007,7 +3007,7 @@ The depth in the expression tree. 0 for top-level elements
optional id: string;
```

id associated with this element or its ancestor, set with `\htmlId` or
id associated with this element or its ancestor, set with `\htmlId` or
`\cssId`

</MemberCard>
Expand Down Expand Up @@ -5990,29 +5990,6 @@ set onScrollIntoView(value): void
#### Localization
<a id="fractionnavigationorder" name="fractionnavigationorder"></a>
<MemberCard>
##### MathfieldElement.fractionNavigationOrder
```ts
static fractionNavigationOrder: "numerator-denominator" | "denominator-numerator" = 'numerator-denominator';
```
When using the keyboard to navigate a fraction, the order in which the
numerator and navigator are traversed:
- "numerator-denominator": first the elements in the numerator, then
the elements in the denominator.
- "denominator-numerator": first the elements in the denominator, then
the elements in the numerator. In some East-Asian cultures, fractions
are read and written denominator first ("fēnzhī"). With this option
the keyboard navigation follows this convention.
**Default**: `"numerator-denominator"`
</MemberCard>
<a id="decimalseparator" name="decimalseparator"></a>
<MemberCard>
Expand Down Expand Up @@ -6047,6 +6024,37 @@ set static decimalSeparator(value): void
</MemberCard>
<a id="fractionnavigationorder" name="fractionnavigationorder"></a>
<MemberCard>
##### MathfieldElement.fractionNavigationOrder
```ts
get static fractionNavigationOrder(): "denominator-numerator" | "numerator-denominator"
```
When using the keyboard to navigate a fraction, the order in which the
numerator and navigator are traversed:
- "numerator-denominator": first the elements in the numerator, then
the elements in the denominator.
- "denominator-numerator": first the elements in the denominator, then
the elements in the numerator. In some East-Asian cultures, fractions
are read and written denominator first ("fēnzhī"). With this option
the keyboard navigation follows this convention.
**Default**: `"numerator-denominator"`
```ts
set static fractionNavigationOrder(s): void
```
• **s**: `"denominator-numerator"` \| `"numerator-denominator"`
`"denominator-numerator"` \| `"numerator-denominator"`
</MemberCard>
<a id="locale" name="locale"></a>
<MemberCard>
Expand Down Expand Up @@ -6407,9 +6415,9 @@ readonly [`Keybinding`](#keybinding)[]
```ts
get letterShapeStyle():
| "auto"
| "french"
| "tex"
| "iso"
| "french"
| "upright"
```
Expand All @@ -6421,15 +6429,15 @@ set letterShapeStyle(value): void
• **value**:
\| `"auto"`
\| `"french"`
\| `"tex"`
\| `"iso"`
\| `"french"`
\| `"upright"`
\| `"auto"`
\| `"french"`
\| `"tex"`
\| `"iso"`
\| `"french"`
\| `"upright"`
</MemberCard>
Expand Down
2 changes: 1 addition & 1 deletion src/atoms/composition.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ParseMode, Style } from '../public/core-types';
import type { ParseMode } from '../public/core-types';

import { Atom } from '../core/atom-class';
import { Box } from '../core/box';
Expand Down
4 changes: 2 additions & 2 deletions src/atoms/genfrac.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { VBox } from '../core/v-box';
import { makeCustomSizedDelim, makeNullDelimiter } from '../core/delimiters';
import { Context } from '../core/context';
import { AXIS_HEIGHT } from '../core/font-metrics';
import type { AtomJson } from 'core/types';
import { _MathEnvironment } from 'core/math-environment';
import type { AtomJson } from '../core/types';
import { _MathEnvironment } from '../core/math-environment';

export type GenfracOptions = {
continuousFraction?: boolean;
Expand Down
2 changes: 1 addition & 1 deletion src/atoms/group.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ParseMode, Style } from '../public/core-types';
import type { ParseMode } from '../public/core-types';

import { Atom } from '../core/atom-class';
import type { Context } from '../core/context';
Expand Down
2 changes: 0 additions & 2 deletions src/atoms/latex.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import type { Style } from '../public/core-types';

import { Atom } from '../core/atom-class';
import { Box } from '../core/box';
import { Context } from '../core/context';
Expand Down
21 changes: 21 additions & 0 deletions src/atoms/subsup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,27 @@ export class SubsupAtom extends Atom {
this.subsupPlacement = 'auto';
}

get children(): Readonly<Atom[]> {
if (!this._children) {
const result: Atom[] = [];

const sub = this.branch('subscript');
if (sub)
for (const x of sub) {
result.push(...x.children);
result.push(x);
}
const sup = this.branch('superscript');
if (sup)
for (const x of sup) {
result.push(...x.children);
result.push(x);
}
this._children = result;
}
return this._children;
}

static fromJson(json: { [key: string]: any }): SubsupAtom {
const result = new SubsupAtom(json as any);
for (const branch of NAMED_BRANCHES)
Expand Down
6 changes: 2 additions & 4 deletions src/core/atom-class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ export class Atom<T extends (Argument | null)[] = (Argument | null)[]> {
}

bodyToLatex(options: ToLatexOptions): string {
let defaultMode =
const defaultMode =
options.defaultMode ?? (this.mode === 'math' ? 'math' : 'text');

return Mode.serialize(this.body, { ...options, defaultMode });
Expand Down Expand Up @@ -549,9 +549,7 @@ export class Atom<T extends (Argument | null)[] = (Argument | null)[]> {
this.style.variant = style.variant;
if (style.variantStyle && !this.style.variantStyle)
this.style.variantStyle = style.variantStyle;
} else {
this.style = { ...this.style, ...style };
}
} else this.style = { ...this.style, ...style };

if (this.style.fontFamily === 'none') delete this.style.fontFamily;

Expand Down
3 changes: 1 addition & 2 deletions src/core/modes-math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,8 @@ function emitBoldRun(run: Atom[], options: ToLatexOptions): string[] {

// Get the content of the run
const value = joinLatex(x.map((x) => x.value ?? ''));
if (/^[a-zA-Z0-9]+$/.test(value)) {
if (/^[a-zA-Z0-9]+$/.test(value))
return latexCommand('\\mathbf', joinLatex(emitVariantRun(x, options)));
}

// If the run contains a mix of characters, use `\bm`
return latexCommand('\\bm', joinLatex(emitVariantRun(x, options)));
Expand Down
4 changes: 2 additions & 2 deletions src/editor-mathfield/autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,9 @@ export function complete(

if (completion === 'reject') return true;

let style = { ...computeInsertStyle(mathfield) };
const style = { ...computeInsertStyle(mathfield) };
// If we're inserting a non-alphanumeric character, reset the variant
if (!/^[a-zA-Z0-9]$/.test(latex) && this.styleBias !== 'none') {
if (!/^[a-zA-Z0-9]$/.test(latex) && mathfield.styleBias !== 'none') {
style.variant = 'normal';
style.variantStyle = undefined;
}
Expand Down
2 changes: 1 addition & 1 deletion src/editor-mathfield/keyboard-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ function insertMathModeChar(mathfield: _Mathfield, c: string): void {
return;
}

let style = { ...computeInsertStyle(mathfield) };
const style = { ...computeInsertStyle(mathfield) };

// If we're inserting a non-alphanumeric character, reset the variant
if (!/[a-zA-Z0-9]/.test(c) && mathfield.styleBias !== 'none') {
Expand Down
17 changes: 8 additions & 9 deletions src/editor-mathfield/mathfield-private.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import type {
Keybinding,
KeyboardLayoutName,
} from '../public/options';
import type { Mathfield } from '../public/mathfield';
import type {
Mathfield,
InsertOptions,
OutputFormat,
Offset,
Range,
Selection,
ApplyStyleOptions,
} from '../public/mathfield';
} from '../public/core-types';

import { canVibrate } from '../ui/utils/capabilities';

Expand Down Expand Up @@ -452,7 +452,7 @@ If you are using Vue, this may be because you are using the runtime-only build o
// to adjust the UI (popover, etc...)
window.addEventListener('resize', this, { signal });
document.addEventListener('scroll', this, { signal });
this.resizeObserver = new ResizeObserver((entries) => {
this.resizeObserver = new ResizeObserver((_entries) => {
if (this.resizeObserverStarted) {
this.resizeObserverStarted = false;
return;
Expand Down Expand Up @@ -1125,7 +1125,7 @@ If you are using Vue, this may be because you are using the runtime-only build o
} else if (s === '&') addColumnAfter(this.model);
else {
if (this.model.selectionIsCollapsed) {
let style = { ...computeInsertStyle(this) };
const style = { ...computeInsertStyle(this) };
// If we're inserting a non-alphanumeric character, reset the variant
if (!/^[a-zA-Z0-9]$/.test(s) && this.styleBias !== 'none') {
style.variant = 'normal';
Expand Down Expand Up @@ -1425,8 +1425,7 @@ If you are using Vue, this may be because you are using the runtime-only build o
locked?: boolean;
correctness?: 'correct' | 'incorrect' | 'undefined';
}): string[] {
return this.model
.getAllAtoms()
return this.model.atoms
.filter((a: PromptAtom) => {
if (a.type !== 'prompt') return false;
if (!filter) return true;
Expand Down Expand Up @@ -1600,11 +1599,11 @@ If you are using Vue, this may be because you are using the runtime-only build o
// If we're at the start or the end of a LaTeX group,
// move inside the group and don't switch mode.
const sibling = model.at(pos + 1);
if (sibling?.type === 'first' && sibling.mode === 'latex') {
if (sibling?.type === 'first' && sibling.mode === 'latex')
model.position = pos + 1;
} else if (latexGroup && sibling?.mode !== 'latex') {
else if (latexGroup && sibling?.mode !== 'latex')
model.position = pos - 1;
} else {
else {
// We may have moved from math to text, or text to math.
this.switchMode(mode);
}
Expand Down
2 changes: 1 addition & 1 deletion src/editor-mathfield/mode-editor-latex.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable no-new */
import { Offset, Range, InsertOptions } from '../public/mathfield';
import { Offset, Range, InsertOptions } from '../public/core-types';
import { LatexAtom, LatexGroupAtom } from '../atoms/latex';
import { range } from '../editor-model/selection-utils';
import { Atom } from '../core/atom-class';
Expand Down
4 changes: 2 additions & 2 deletions src/editor-mathfield/mode-editor-math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import type { Expression } from '@cortex-js/compute-engine/dist/types/math-json/math-json-format';

import { InsertOptions, Offset, OutputFormat } from '../public/mathfield';
import type { InsertOptions, Offset, OutputFormat } from '../public/core-types';

import { requestUpdate } from './render';

Expand Down Expand Up @@ -169,7 +169,7 @@ export class MathModeEditor extends ModeEditor {
}

insert(model: _Model, input: string, options: InsertOptions): boolean {
let data =
const data =
typeof input === 'string'
? input
: globalThis.MathfieldElement.computeEngine?.box(input).latex ?? '';
Expand Down
4 changes: 2 additions & 2 deletions src/editor-mathfield/mode-editor-text.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* eslint-disable no-new */
import type { InsertOptions } from '../public/mathfield';
import type { InsertOptions } from '../public/core-types';

import { parseLatex } from '../core/core';
import type { ContextInterface } from '../core/types';
import { Atom } from '../core/atom-class';
import { _Model } from '../editor-model/model-private';
import { range } from '../editor-model/selection-utils';
Expand All @@ -10,7 +11,6 @@ import { applyStyleToUnstyledAtoms } from '../editor-model/styling';
import { _Mathfield } from './mathfield-private';
import { ModeEditor } from './mode-editor';
import { requestUpdate } from './render';
import type { ContextInterface } from '../core/types';

export class TextModeEditor extends ModeEditor {
constructor() {
Expand Down
2 changes: 1 addition & 1 deletion src/editor-mathfield/mode-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { TextAtom } from '../atoms/text';
import { _Model } from '../editor-model/model-private';
import { range } from '../editor-model/selection-utils';
import { MODE_SHIFT_COMMANDS } from '../formats/parse-math-string';
import { InsertOptions, OutputFormat, Range } from '../public/mathfield';
import type { InsertOptions, OutputFormat, Range } from '../public/core-types';
import { _Mathfield } from './mathfield-private';

const CLIPBOARD_LATEX_BEGIN = '$$';
Expand Down
2 changes: 1 addition & 1 deletion src/editor-mathfield/pointer-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { requestUpdate } from './render';
import { Atom } from '../core/atom-class';
import { acceptCommandSuggestion } from './autocomplete';
import { selectGroup } from '../editor-model/commands-select';
import type { Offset } from 'public/mathfield';
import type { Offset } from 'public/core-types';

let gLastTap: { x: number; y: number; time: number } | null = null;
let gTapCount = 0;
Expand Down
7 changes: 2 additions & 5 deletions src/editor-mathfield/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,7 @@ export function render(
)
hideMenu = true;
// If the width of the element is less than 50px, hide the menu
if (!hideMenu && field.offsetWidth < 50) {
hideMenu = true;
}
if (!hideMenu && field.offsetWidth < 50) hideMenu = true;

menuToggle.style.display = hideMenu ? 'none' : '';
}
Expand Down Expand Up @@ -426,7 +424,6 @@ export function reparse(mathfield: _Mathfield | null): void {
}

export function reparseAllMathfields(): void {
for (const mathfield of document.querySelectorAll('.ML__mathfield')) {
for (const mathfield of document.querySelectorAll('.ML__mathfield'))
if ('_mathfield' in mathfield) reparse(mathfield._mathfield as _Mathfield);
}
}
3 changes: 2 additions & 1 deletion src/editor-mathfield/styling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,12 @@ export function defaultInsertStyleHook(
if (bias === 'none') return mathfield.defaultStyle;

// In text mode, we inherit the style of the sibling atom
if (model.mode === 'text')
if (model.mode === 'text') {
return (
model.at(bias === 'right' ? info.after : info.before)?.style ??
mathfield.defaultStyle
);
}

if (model.mode === 'math') {
const atom = model.at(bias === 'right' ? info.after : info.before);
Expand Down
Loading

0 comments on commit 283b3f6

Please sign in to comment.