@pie-lib/math-input-mathlive 1.0.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 +119 -0
- package/lib/__tests__/index.test.js +118 -0
- package/lib/__tests__/index.test.js.map +1 -0
- package/lib/__tests__/latex-bridge.test.js +186 -0
- package/lib/__tests__/latex-bridge.test.js.map +1 -0
- package/lib/__tests__/mathlive-instance.test.js +137 -0
- package/lib/__tests__/mathlive-instance.test.js.map +1 -0
- package/lib/horizontal-keypad.js +101 -0
- package/lib/horizontal-keypad.js.map +1 -0
- package/lib/index.js +143 -0
- package/lib/index.js.map +1 -0
- package/lib/keypad/index.js +365 -0
- package/lib/keypad/index.js.map +1 -0
- package/lib/keypad/keys-layout.js +22 -0
- package/lib/keypad/keys-layout.js.map +1 -0
- package/lib/keys/basic-operators.js +33 -0
- package/lib/keys/basic-operators.js.map +1 -0
- package/lib/keys/chars.js +12 -0
- package/lib/keys/chars.js.map +1 -0
- package/lib/keys/comparison.js +39 -0
- package/lib/keys/comparison.js.map +1 -0
- package/lib/keys/constants.js +37 -0
- package/lib/keys/constants.js.map +1 -0
- package/lib/keys/digits.js +46 -0
- package/lib/keys/digits.js.map +1 -0
- package/lib/keys/edit.js +14 -0
- package/lib/keys/edit.js.map +1 -0
- package/lib/keys/exponent.js +30 -0
- package/lib/keys/exponent.js.map +1 -0
- package/lib/keys/fractions.js +29 -0
- package/lib/keys/fractions.js.map +1 -0
- package/lib/keys/geometry.js +140 -0
- package/lib/keys/geometry.js.map +1 -0
- package/lib/keys/grades.js +259 -0
- package/lib/keys/grades.js.map +1 -0
- package/lib/keys/index.js +35 -0
- package/lib/keys/index.js.map +1 -0
- package/lib/keys/log.js +27 -0
- package/lib/keys/log.js.map +1 -0
- package/lib/keys/logic.js +19 -0
- package/lib/keys/logic.js.map +1 -0
- package/lib/keys/matrices.js +19 -0
- package/lib/keys/matrices.js.map +1 -0
- package/lib/keys/misc.js +62 -0
- package/lib/keys/misc.js.map +1 -0
- package/lib/keys/navigation.js +20 -0
- package/lib/keys/navigation.js.map +1 -0
- package/lib/keys/operators.js +15 -0
- package/lib/keys/operators.js.map +1 -0
- package/lib/keys/statistics.js +40 -0
- package/lib/keys/statistics.js.map +1 -0
- package/lib/keys/sub-sup.js +19 -0
- package/lib/keys/sub-sup.js.map +1 -0
- package/lib/keys/trigonometry.js +45 -0
- package/lib/keys/trigonometry.js.map +1 -0
- package/lib/keys/utils.js +87 -0
- package/lib/keys/utils.js.map +1 -0
- package/lib/keys/vars.js +24 -0
- package/lib/keys/vars.js.map +1 -0
- package/lib/latex-bridge.js +195 -0
- package/lib/latex-bridge.js.map +1 -0
- package/lib/math-input.js +143 -0
- package/lib/math-input.js.map +1 -0
- package/lib/mathlive-instance.js +319 -0
- package/lib/mathlive-instance.js.map +1 -0
- package/lib/mf/common-styles.js +111 -0
- package/lib/mf/common-styles.js.map +1 -0
- package/lib/mf/index.js +72 -0
- package/lib/mf/index.js.map +1 -0
- package/lib/mf/input.js +266 -0
- package/lib/mf/input.js.map +1 -0
- package/lib/mf/static.js +396 -0
- package/lib/mf/static.js.map +1 -0
- package/package.json +31 -0
- package/src/__tests__/index.test.jsx +109 -0
- package/src/__tests__/latex-bridge.test.js +151 -0
- package/src/__tests__/mathlive-instance.test.js +130 -0
- package/src/horizontal-keypad.jsx +73 -0
- package/src/index.jsx +63 -0
- package/src/keypad/index.jsx +335 -0
- package/src/keypad/keys-layout.js +16 -0
- package/src/keys/basic-operators.js +32 -0
- package/src/keys/chars.js +5 -0
- package/src/keys/comparison.js +28 -0
- package/src/keys/constants.js +35 -0
- package/src/keys/digits.js +40 -0
- package/src/keys/edit.js +3 -0
- package/src/keys/exponent.js +28 -0
- package/src/keys/fractions.js +26 -0
- package/src/keys/geometry.js +144 -0
- package/src/keys/grades.js +367 -0
- package/src/keys/index.js +20 -0
- package/src/keys/log.js +22 -0
- package/src/keys/logic.js +15 -0
- package/src/keys/matrices.js +15 -0
- package/src/keys/misc.js +65 -0
- package/src/keys/navigation.js +8 -0
- package/src/keys/operators.js +10 -0
- package/src/keys/statistics.js +38 -0
- package/src/keys/sub-sup.js +15 -0
- package/src/keys/trigonometry.js +15 -0
- package/src/keys/utils.js +66 -0
- package/src/keys/vars.js +19 -0
- package/src/latex-bridge.js +190 -0
- package/src/math-input.jsx +115 -0
- package/src/mathlive-instance.js +286 -0
- package/src/mf/common-styles.js +108 -0
- package/src/mf/index.js +26 -0
- package/src/mf/input.jsx +223 -0
- package/src/mf/static.jsx +358 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import {
|
|
2
|
+
toMathLive,
|
|
3
|
+
fromMathLive,
|
|
4
|
+
fieldIds,
|
|
5
|
+
keyToAction,
|
|
6
|
+
NEWLINE_EMBED,
|
|
7
|
+
DEFAULT_FIELD_ID,
|
|
8
|
+
} from '../latex-bridge';
|
|
9
|
+
|
|
10
|
+
describe('latex-bridge', () => {
|
|
11
|
+
describe('toMathLive', () => {
|
|
12
|
+
it('passes plain latex through', () => {
|
|
13
|
+
expect(toMathLive('\\frac{1}{2}')).toEqual('\\frac{1}{2}');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('handles empty/nullish', () => {
|
|
17
|
+
expect(toMathLive('')).toEqual('');
|
|
18
|
+
expect(toMathLive(undefined)).toEqual('');
|
|
19
|
+
expect(toMathLive(null)).toEqual('');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('converts a newLine embed to a multiline environment', () => {
|
|
23
|
+
expect(toMathLive(`a${NEWLINE_EMBED}b`)).toEqual('\\displaylines{a \\\\ b}');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('converts multiple newLine embeds', () => {
|
|
27
|
+
expect(toMathLive(`a${NEWLINE_EMBED}b${NEWLINE_EMBED}c`)).toEqual('\\displaylines{a \\\\ b \\\\ c}');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('converts MathQuill answer blocks to placeholders', () => {
|
|
31
|
+
expect(toMathLive('x=\\MathQuillMathField[r1]{}')).toEqual('x=\\placeholder[r1]{}');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('preserves answer block content', () => {
|
|
35
|
+
expect(toMathLive('\\MathQuillMathField[r2]{7}')).toEqual('\\placeholder[r2]{7}');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('defaults an unnamed answer block id', () => {
|
|
39
|
+
expect(toMathLive('\\MathQuillMathField[]{}')).toEqual(`\\placeholder[${DEFAULT_FIELD_ID}]{}`);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('handles answer blocks and newlines together', () => {
|
|
43
|
+
expect(toMathLive(`\\MathQuillMathField[r1]{}${NEWLINE_EMBED}x`)).toEqual(
|
|
44
|
+
'\\displaylines{\\placeholder[r1]{} \\\\ x}',
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('fromMathLive', () => {
|
|
50
|
+
it('passes plain latex through', () => {
|
|
51
|
+
expect(fromMathLive('\\frac{1}{2}')).toEqual('\\frac{1}{2}');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('unwraps displaylines back to newLine embeds', () => {
|
|
55
|
+
expect(fromMathLive('\\displaylines{a \\\\ b}')).toEqual(`a${NEWLINE_EMBED}b`);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('converts placeholders back to MathQuill answer blocks', () => {
|
|
59
|
+
expect(fromMathLive('x=\\placeholder[r1]{}')).toEqual('x=\\MathQuillMathField[r1]{}');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('round-trips a newline document', () => {
|
|
63
|
+
const stored = `a${NEWLINE_EMBED}b${NEWLINE_EMBED}c`;
|
|
64
|
+
|
|
65
|
+
expect(fromMathLive(toMathLive(stored))).toEqual(stored);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('round-trips an answer-block document', () => {
|
|
69
|
+
const stored = 'x=\\MathQuillMathField[r1]{}+\\MathQuillMathField[r2]{3}';
|
|
70
|
+
|
|
71
|
+
expect(fromMathLive(toMathLive(stored))).toEqual(stored);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('round-trips answer blocks combined with newlines', () => {
|
|
75
|
+
const stored = `\\MathQuillMathField[r1]{}${NEWLINE_EMBED}y`;
|
|
76
|
+
|
|
77
|
+
expect(fromMathLive(toMathLive(stored))).toEqual(stored);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('fieldIds', () => {
|
|
82
|
+
it('returns ids in document order', () => {
|
|
83
|
+
expect(fieldIds('\\MathQuillMathField[r1]{}+\\MathQuillMathField[r2]{}')).toEqual(['r1', 'r2']);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('returns [] when there are none', () => {
|
|
87
|
+
expect(fieldIds('x+y')).toEqual([]);
|
|
88
|
+
expect(fieldIds(undefined)).toEqual([]);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('is repeatable (regex lastIndex is reset)', () => {
|
|
92
|
+
const latex = '\\MathQuillMathField[r1]{}';
|
|
93
|
+
|
|
94
|
+
expect(fieldIds(latex)).toEqual(['r1']);
|
|
95
|
+
expect(fieldIds(latex)).toEqual(['r1']);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe('keyToAction', () => {
|
|
100
|
+
it('prefers latex when there is no command', () => {
|
|
101
|
+
expect(keyToAction({ latex: '\\pi', write: 'p' })).toEqual({ type: 'insert', value: '\\pi' });
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('uses write', () => {
|
|
105
|
+
expect(keyToAction({ write: 'x' })).toEqual({ type: 'insert', value: 'x' });
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('expands commands that take arguments into placeholders', () => {
|
|
109
|
+
expect(keyToAction({ command: '\\frac' })).toEqual({ type: 'insert', value: '\\frac{#?}{#?}' });
|
|
110
|
+
expect(keyToAction({ command: '\\sqrt' })).toEqual({ type: 'insert', value: '\\sqrt{#?}' });
|
|
111
|
+
expect(keyToAction({ command: '^' })).toEqual({ type: 'insert', value: '^{#?}' });
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('passes argument-less commands through', () => {
|
|
115
|
+
expect(keyToAction({ command: '\\pi' })).toEqual({ type: 'insert', value: '\\pi' });
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('concatenates array commands (MathQuill cmd() applied them in sequence)', () => {
|
|
119
|
+
// Measured Angle
|
|
120
|
+
expect(keyToAction({ command: ['m', '\\angle'] })).toEqual({ type: 'insert', value: 'm\\angle' });
|
|
121
|
+
// log base n - the `_` part must still expand to a placeholder
|
|
122
|
+
expect(keyToAction({ command: ['\\log', '_'] })).toEqual({ type: 'insert', value: '\\log_{#?}' });
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('always returns a string value for insert actions', () => {
|
|
126
|
+
[{ command: ['m', '\\angle'] }, { command: '\\frac' }, { write: 'x' }, { latex: '\\pi' }].forEach((k) => {
|
|
127
|
+
expect(typeof keyToAction(k).value).toBe('string');
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('maps keystrokes to MathLive selectors', () => {
|
|
132
|
+
expect(keyToAction({ keystroke: 'Left' })).toEqual({ type: 'command', value: 'moveToPreviousChar' });
|
|
133
|
+
expect(keyToAction({ keystroke: 'Right' })).toEqual({ type: 'command', value: 'moveToNextChar' });
|
|
134
|
+
expect(keyToAction({ keystroke: 'Backspace' })).toEqual({ type: 'command', value: 'deleteBackward' });
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('returns undefined for unknown/empty input', () => {
|
|
138
|
+
expect(keyToAction(undefined)).toBeUndefined();
|
|
139
|
+
expect(keyToAction({})).toBeUndefined();
|
|
140
|
+
expect(keyToAction({ keystroke: 'Nope' })).toBeUndefined();
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('latex wins over command only when command is absent', () => {
|
|
144
|
+
// a key with both should use the command path (matches MathInput.keypadPress)
|
|
145
|
+
expect(keyToAction({ latex: '\\frac{}{}', command: '\\frac' })).toEqual({
|
|
146
|
+
type: 'insert',
|
|
147
|
+
value: '\\frac{#?}{#?}',
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
});
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
describe('mathlive-instance', () => {
|
|
2
|
+
let instance;
|
|
3
|
+
|
|
4
|
+
beforeEach(() => {
|
|
5
|
+
jest.resetModules();
|
|
6
|
+
// eslint-disable-next-line global-require
|
|
7
|
+
instance = require('../mathlive-instance');
|
|
8
|
+
instance.__resetEmbeds();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
describe('registerEmbed', () => {
|
|
12
|
+
it('registers a known embed and exposes it as a macro', () => {
|
|
13
|
+
instance.registerEmbed('answerBlock', () => ({
|
|
14
|
+
htmlString: '<div class="answerBlock"></div>',
|
|
15
|
+
latex: () => '\\embed{answerBlock}[]',
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
expect(instance.registeredEmbeds()).toEqual(['answerBlock']);
|
|
19
|
+
// The macro tags output with data-embed so CSS can target it, replacing
|
|
20
|
+
// MathQuill's htmlString hook.
|
|
21
|
+
expect(instance.getMacros().answerBlock).toEqual('\\htmlData{embed=answerBlock}{\\placeholder{}}');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('registers newLine as a harmless macro (it is handled by latex-bridge)', () => {
|
|
25
|
+
instance.registerEmbed('newLine', () => ({ latex: () => '\\embed{newLine}[]' }));
|
|
26
|
+
|
|
27
|
+
expect(instance.getMacros().newLine).toEqual('\\htmlData{embed=newLine}{}');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('falls back to a placeholder for an unknown embed', () => {
|
|
31
|
+
instance.registerEmbed('somethingCustom', () => ({ htmlString: '<b>x</b>' }));
|
|
32
|
+
|
|
33
|
+
expect(instance.getMacros().somethingCustom).toEqual('\\htmlData{embed=somethingCustom}{\\placeholder{}}');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('honours an explicit mathliveLatex from the factory', () => {
|
|
37
|
+
instance.registerEmbed('custom', () => ({ mathliveLatex: '\\alpha' }));
|
|
38
|
+
|
|
39
|
+
expect(instance.getMacros().custom).toEqual('\\htmlData{embed=custom}{\\alpha}');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('does not throw when the factory throws', () => {
|
|
43
|
+
expect(() => instance.registerEmbed('bad', () => {
|
|
44
|
+
throw new Error('boom');
|
|
45
|
+
})).not.toThrow();
|
|
46
|
+
|
|
47
|
+
expect(instance.registeredEmbeds()).toEqual(['bad']);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('ignores bad arguments', () => {
|
|
51
|
+
instance.registerEmbed(undefined, () => ({}));
|
|
52
|
+
instance.registerEmbed('noFactory', undefined);
|
|
53
|
+
|
|
54
|
+
expect(instance.registeredEmbeds()).toEqual([]);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('always includes the pie macro set', () => {
|
|
58
|
+
const macros = instance.getMacros();
|
|
59
|
+
|
|
60
|
+
expect(macros.parallelogram).toBeDefined();
|
|
61
|
+
expect(macros.longdiv).toBeDefined();
|
|
62
|
+
expect(macros.napprox).toEqual('\\not\\approx');
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe('applyStaticMath', () => {
|
|
67
|
+
it('returns undefined without an element', () => {
|
|
68
|
+
expect(instance.applyStaticMath(null, 'x')).toBeUndefined();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('returns undefined when MathLive has not loaded', () => {
|
|
72
|
+
const el = document.createElement('div');
|
|
73
|
+
|
|
74
|
+
expect(instance.applyStaticMath(el, 'x')).toBeUndefined();
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe('configureFonts', () => {
|
|
79
|
+
// MathLive's default fontsDirectory is the relative './fonts/', which it
|
|
80
|
+
// resolves against its own (empty, when bundled) script url and throws
|
|
81
|
+
// "Invalid base URL" from loadFonts. Paths must become absolute.
|
|
82
|
+
it('is exported and callable before MathLive loads', () => {
|
|
83
|
+
expect(typeof instance.configureFonts).toBe('function');
|
|
84
|
+
expect(() => instance.configureFonts('/mathlive-fonts')).not.toThrow();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('accepts null to disable font loading', () => {
|
|
88
|
+
expect(() => instance.configureFonts(null)).not.toThrow();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('applies an absolute url to an already-loaded MathfieldElement', () => {
|
|
92
|
+
const MathfieldElement = {};
|
|
93
|
+
|
|
94
|
+
// simulate a loaded instance
|
|
95
|
+
instance.__setMathLiveForTest({ MathfieldElement });
|
|
96
|
+
instance.configureFonts('/mathlive-fonts');
|
|
97
|
+
|
|
98
|
+
expect(MathfieldElement.fontsDirectory).toEqual(`${document.baseURI.replace(/\/$/, '')}/mathlive-fonts`);
|
|
99
|
+
expect(MathfieldElement.fontsDirectory.startsWith('http')).toBe(true);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('leaves a fully-qualified url untouched', () => {
|
|
103
|
+
const MathfieldElement = {};
|
|
104
|
+
|
|
105
|
+
instance.__setMathLiveForTest({ MathfieldElement });
|
|
106
|
+
instance.configureFonts('https://cdn.example.com/fonts');
|
|
107
|
+
|
|
108
|
+
expect(MathfieldElement.fontsDirectory).toEqual('https://cdn.example.com/fonts');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('passes null through rather than resolving it', () => {
|
|
112
|
+
const MathfieldElement = {};
|
|
113
|
+
|
|
114
|
+
instance.__setMathLiveForTest({ MathfieldElement });
|
|
115
|
+
instance.configureFonts(null);
|
|
116
|
+
|
|
117
|
+
expect(MathfieldElement.fontsDirectory).toBeNull();
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe('latexToMarkup', () => {
|
|
122
|
+
it('returns empty string when MathLive is not loaded', () => {
|
|
123
|
+
expect(instance.latexToMarkup('\\pi')).toEqual('');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('returns empty string for empty latex', () => {
|
|
127
|
+
expect(instance.latexToMarkup('')).toEqual('');
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { keysForGrade, normalizeAdditionalKeys } from './keys/grades';
|
|
4
|
+
import { extendKeySet } from './keys/utils';
|
|
5
|
+
import Keypad from './keypad';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Maps a key definition to the legacy `{value, type}` shape that
|
|
9
|
+
* @pie-lib/math-toolbar consumes. Unchanged from the MathQuill implementation:
|
|
10
|
+
* the shape is part of the 4.x-compatible contract, and translation to MathLive
|
|
11
|
+
* happens later, in `latex-bridge.keyToAction`.
|
|
12
|
+
*/
|
|
13
|
+
const toOldModel = (d) => {
|
|
14
|
+
if (d.command) {
|
|
15
|
+
return { value: d.command, type: 'command' };
|
|
16
|
+
} else if (d.write) {
|
|
17
|
+
return { value: d.write };
|
|
18
|
+
} else if (d.keystroke) {
|
|
19
|
+
return { type: 'cursor', value: d.keystroke };
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default class HorizontalKeypad extends React.Component {
|
|
24
|
+
static propTypes = {
|
|
25
|
+
className: PropTypes.string,
|
|
26
|
+
controlledKeypadMode: PropTypes.bool,
|
|
27
|
+
mode: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
28
|
+
layoutForKeyPad: PropTypes.object,
|
|
29
|
+
onClick: PropTypes.func.isRequired,
|
|
30
|
+
onFocus: PropTypes.func,
|
|
31
|
+
noDecimal: PropTypes.bool,
|
|
32
|
+
additionalKeys: PropTypes.array,
|
|
33
|
+
setKeypadInteraction: PropTypes.func,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
static defaultProps = {
|
|
37
|
+
mode: 'scientific',
|
|
38
|
+
noDecimal: false,
|
|
39
|
+
additionalKeys: [],
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
keypadPress = (data) => {
|
|
43
|
+
this.props.onClick(toOldModel(data));
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
render() {
|
|
47
|
+
const {
|
|
48
|
+
mode,
|
|
49
|
+
onFocus,
|
|
50
|
+
controlledKeypadMode,
|
|
51
|
+
noDecimal,
|
|
52
|
+
className,
|
|
53
|
+
additionalKeys,
|
|
54
|
+
layoutForKeyPad,
|
|
55
|
+
setKeypadInteraction,
|
|
56
|
+
} = this.props;
|
|
57
|
+
const normalizedKeys = normalizeAdditionalKeys(additionalKeys);
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<Keypad
|
|
61
|
+
className={className}
|
|
62
|
+
controlledKeypadMode={controlledKeypadMode}
|
|
63
|
+
onFocus={onFocus}
|
|
64
|
+
noDecimal={noDecimal}
|
|
65
|
+
layoutForKeyPad={layoutForKeyPad}
|
|
66
|
+
additionalKeys={extendKeySet(keysForGrade(mode), normalizedKeys)}
|
|
67
|
+
onPress={this.keypadPress}
|
|
68
|
+
mode={mode}
|
|
69
|
+
setKeypadInteraction={setKeypadInteraction}
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/index.jsx
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { keysForGrade } from './keys/grades';
|
|
2
|
+
import * as keys from './keys';
|
|
3
|
+
|
|
4
|
+
import MathInput from './math-input';
|
|
5
|
+
import HorizontalKeypad from './horizontal-keypad';
|
|
6
|
+
import KeyPad from './keypad';
|
|
7
|
+
|
|
8
|
+
import * as mf from './mf';
|
|
9
|
+
import {
|
|
10
|
+
registerEmbed,
|
|
11
|
+
applyStaticMath,
|
|
12
|
+
latexToMarkup,
|
|
13
|
+
loadMathLive,
|
|
14
|
+
configureFonts,
|
|
15
|
+
getMacros,
|
|
16
|
+
PIE_MACROS,
|
|
17
|
+
} from './mathlive-instance';
|
|
18
|
+
import { toMathLive, fromMathLive, keyToAction, NEWLINE_EMBED } from './latex-bridge';
|
|
19
|
+
|
|
20
|
+
const addLeftBracket = (s) => (s.indexOf('\\(') === 0 ? s : `\\(${s}`);
|
|
21
|
+
const addRightBracket = (s) => (s.indexOf('\\)') === s.length - 2 ? s : `${s}\\)`);
|
|
22
|
+
const rmLeftBracket = (s) => (s.indexOf('\\(') === 0 ? s.substring(2) : s);
|
|
23
|
+
const rmRightBracket = (s) => (s.indexOf('\\)') === s.length - 2 ? s.substring(0, s.length - 2) : s);
|
|
24
|
+
|
|
25
|
+
const addBrackets = (s) => addRightBracket(addLeftBracket(s));
|
|
26
|
+
const removeBrackets = (s) => rmRightBracket(rmLeftBracket(s));
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* `updateSpans` is intentionally a no-op.
|
|
30
|
+
*
|
|
31
|
+
* In @pie-lib/math-input it patched MathQuill's rendered DOM by walking
|
|
32
|
+
* `span[mathquill-command-id]` to resize the parallel glyph and tag primes.
|
|
33
|
+
* MathLive emits none of those attributes and does not need the fixups, but the
|
|
34
|
+
* export is kept so callers do not break.
|
|
35
|
+
*/
|
|
36
|
+
const updateSpans = () => {};
|
|
37
|
+
|
|
38
|
+
export {
|
|
39
|
+
keysForGrade,
|
|
40
|
+
addBrackets,
|
|
41
|
+
removeBrackets,
|
|
42
|
+
keys,
|
|
43
|
+
MathInput,
|
|
44
|
+
HorizontalKeypad,
|
|
45
|
+
KeyPad,
|
|
46
|
+
updateSpans,
|
|
47
|
+
// `mf` is the MathLive equivalent of math-input's `mq`. Both names are
|
|
48
|
+
// exported so a consumer can switch packages by changing only the import.
|
|
49
|
+
mf,
|
|
50
|
+
mf as mq,
|
|
51
|
+
registerEmbed,
|
|
52
|
+
applyStaticMath,
|
|
53
|
+
// MathLive-specific additions
|
|
54
|
+
latexToMarkup,
|
|
55
|
+
loadMathLive,
|
|
56
|
+
configureFonts,
|
|
57
|
+
getMacros,
|
|
58
|
+
PIE_MACROS,
|
|
59
|
+
toMathLive,
|
|
60
|
+
fromMathLive,
|
|
61
|
+
keyToAction,
|
|
62
|
+
NEWLINE_EMBED,
|
|
63
|
+
};
|