Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Newline command #1931

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
4 changes: 4 additions & 0 deletions css/core.less
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@
padding: 0 0.5em;
}

.ML__newline {
display: block;
}

.ML__frac-line {
width: 100%;
min-height: 1px;
Expand Down
1 change: 1 addition & 0 deletions src/addons/definitions-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,7 @@ metadata(
RARE,
'\\unicode{"203A}$0{1em}\\unicode{"2039}'
);
metadata('Spacing', ['\\\\'], COMMON); // New Line
metadata(
'Punctuation',
[
Expand Down
4 changes: 4 additions & 0 deletions src/addons/math-ml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,10 @@ function atomToMathML(atom, options): string {
case 'overlap':
break;

case 'newline':
result += '<mspace linebreak="newline"></mspace>';
break;

case 'overunder':
overscript = atom.above;
underscript = atom.below;
Expand Down
35 changes: 35 additions & 0 deletions src/core-atoms/newline.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Atom, AtomJson } from '../core/atom-class';
import { Box } from '../core/box';
import { Context } from '../core/context';

import type { ParseMode, Style } from '../public/core-types';
import type { GlobalContext } from '../core/types';

export class NewLineAtom extends Atom {
constructor(command: string, context: GlobalContext, style: Style) {
super('newline', context, { command, style });
this.skipBoundary = true;
}

static fromJson(json: AtomJson, context: GlobalContext): NewLineAtom {
return new NewLineAtom(json.command, context, json as any);
}

toJson(): AtomJson {
return super.toJson();
}

render(context: Context): Box | null {
const box = new Box(null, {
classes: 'ML__newline',
type: 'newline',
});
box.caret = (this.caret as ParseMode) ?? null;
this.bind(context, box);
return box;
}

serialize(): string {
return '\\\\';
}
}
7 changes: 7 additions & 0 deletions src/core-definitions/styling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import type {
import { GlobalContext, PrivateStyle } from '../core/types';
import { latexCommand } from '../core/tokenizer';
import { atomsBoxType } from '../core/box';
import { NewLineAtom } from '../core-atoms/newline';

defineFunction('mathtip', '{:math}{:math}', {
createAtom: (
Expand Down Expand Up @@ -818,6 +819,12 @@ defineFunction('mspace', '{width:glue}', {
),
});

// New line
defineFunction('\\', '', {
createAtom: (command, context, style) =>
new NewLineAtom(command, context, style),
});

defineFunction('mathop', '{:auto}', {
createAtom: (
name: string,
Expand Down
11 changes: 11 additions & 0 deletions src/core/atom-class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ export type AtomType =
| 'leftright' // Used by the `\left` and `\right` commands
| 'line' // Used by `\overline` and `\underline`
| 'macro'
| 'newline' // New line command: `\\`
| 'subsup' // A carrier for a superscript/subscript
| 'overlap' // Display a symbol _over_ another
| 'overunder' // Displays an annotation above or below a symbol
Expand Down Expand Up @@ -565,6 +566,16 @@ export class Atom {
return false;
}

get isInArrayAtom(): boolean {
// eslint-disable-next-line @typescript-eslint/no-this-alias
let atom: Atom | undefined = this;
while (atom) {
if (atom.type === 'array') return true;
atom = atom.parent;
}
return false;
}

/** Return the parent editable prompt, if it exists */
get parentPrompt(): Atom | null {
// eslint-disable-next-line @typescript-eslint/no-this-alias
Expand Down
2 changes: 2 additions & 0 deletions src/core/atom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { SurdAtom } from '../core-atoms/surd';
import { TextAtom } from '../core-atoms/text';
import { TooltipAtom } from '../core-atoms/tooltip';
import { PromptAtom } from '../core-atoms/prompt';
import { NewLineAtom } from '../core-atoms/newline';
import type { GlobalContext } from '../core/types';

export * from './atom-class';
Expand Down Expand Up @@ -69,6 +70,7 @@ export function fromJson(
if (type === 'leftright') result = LeftRightAtom.fromJson(json, context);
if (type === 'line') result = LineAtom.fromJson(json, context);
if (type === 'macro') result = MacroAtom.fromJson(json, context);
if (type === 'newline') result = NewLineAtom.fromJson(json, context);
if (type === 'subsup') result = SubsupAtom.fromJson(json, context);
if (type === 'overlap') result = OverlapAtom.fromJson(json, context);
if (type === 'overunder') result = OverunderAtom.fromJson(json, context);
Expand Down
1 change: 1 addition & 0 deletions src/core/box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,7 @@ function applyInterAtomSpacing(root: Box | null, context: Context): void {
if (!prevBox?.type) return;
// console.log(prevBox?.value, prevBox?.type, box.value, box.type);
const prevType = prevBox.type;
if (prevType === 'newline') return;
const table = box.isTight
? INTER_BOX_TIGHT_SPACING[prevType] ?? null
: INTER_BOX_SPACING[prevType] ?? null;
Expand Down
1 change: 1 addition & 0 deletions src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const BOX_TYPE = [
'close', // > is a closing atom like `)`
'punct', // > is a punctuation atom like ‘,’
'inner', // > is an inner atom like `\frac12`
'newline', // > is a new line box
'spacing',
'first',
'latex',
Expand Down
11 changes: 6 additions & 5 deletions src/editor-mathfield/mathfield-private.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1072,11 +1072,12 @@ If you are using Vue, this may be because you are using the runtime-only build o

if (options.scrollIntoView) this.scrollIntoView();

if (s === '\\\\') {
// This string is interpreted as an "insert row after" command
addRowAfter(this.model);
} else if (s === '&') addColumnAfter(this.model);
else {
if (this.model.at(this.model.position).isInArrayAtom) {
if (s === '\\\\') {
// This string is interpreted as an "insert row after" command
addRowAfter(this.model);
} else if (s === '&') addColumnAfter(this.model);
} else {
const savedStyle = this.style;
ModeEditor.insert(this.mode, this.model, s, {
style: this.model.at(this.model.position).computedStyle,
Expand Down
3 changes: 3 additions & 0 deletions src/editor/keybindings-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ export const DEFAULT_KEYBINDINGS: Keybinding[] = [
}, // Complete the suggestion
{ key: '[Return]', ifMode: 'latex', command: 'complete' },
{ key: '[Enter]', ifMode: 'latex', command: 'complete' },
{ key: '[Return]', ifMode: 'math', command: ['insert', '\\\\'] },
{ key: '[Enter]', ifMode: 'math', command: ['insert', '\\\\'] },
{ key: '[NumpadEnter]', ifMode: 'math', command: ['insert', '\\\\'] },
{
key: 'shift+[Escape]',
ifMode: 'latex',
Expand Down
6 changes: 3 additions & 3 deletions src/virtual-keyboard/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export const LAYOUTS: Record<string, VirtualKeyboardLayout> = {
'[separator-5]',
'[left]',
'[right]',
{ label: '[action]', width: 1.0 },
{ label: '[return]', width: 1.0 },
],
],
},
Expand Down Expand Up @@ -372,7 +372,7 @@ export const LAYOUTS: Record<string, VirtualKeyboardLayout> = {

'[left]',
'[right]',
'[action]',
'[return]',
],
],
},
Expand Down Expand Up @@ -660,7 +660,7 @@ export const LAYOUTS: Record<string, VirtualKeyboardLayout> = {
width: 1.0,
class: 'action hide-shift',
},
{ label: '[action]', width: 1.0 },
{ label: '[return]', width: 1.0 },
],
],
},
Expand Down
5 changes: 3 additions & 2 deletions src/virtual-keyboard/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ function alphabeticLayout(): NormalizedVirtualKeyboardLayout {
'[.]',
'[left]',
'[right]',
{ label: '[action]', width: 1.5 },
{ label: '[return]', width: 1.5 },
]);

return {
Expand Down Expand Up @@ -735,7 +735,8 @@ const KEYCAP_SHORTCUTS: Record<string, Partial<VirtualKeyboardKeycap>> = {
},
'[return]': {
class: 'action',
command: ['performWithFeedback', 'commit'],
insert: '\\\\',
shift: { command: ['performWithFeedback', 'commit'] },
width: 1.5,
label: '<svg class=svg-glyph><use xlink:href=#svg-commit /></svg>',
},
Expand Down