@zzish/math-rich-input 0.1.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 +253 -0
- package/babel.config.js +6 -0
- package/dist/index.js +23034 -0
- package/dist/math-rich-input.css +923 -0
- package/package.json +44 -0
- package/rollup.config.js +31 -0
- package/src/AccentBar.css +169 -0
- package/src/AccentBar.jsx +771 -0
- package/src/EquationEditor.css +258 -0
- package/src/EquationEditor.jsx +583 -0
- package/src/EquationEditorModal.css +164 -0
- package/src/EquationEditorModal.jsx +81 -0
- package/src/MathRichArea.jsx +103 -0
- package/src/MathRichInput.css +63 -0
- package/src/MathRichInput.jsx +1651 -0
- package/src/SymbolButton.css +130 -0
- package/src/SymbolButton.jsx +96 -0
- package/src/Toolbar.css +142 -0
- package/src/Toolbar.jsx +219 -0
- package/src/equationEditorButtonsHelper.js +590 -0
- package/src/index.js +5 -0
- package/src/katexHelper.js +39 -0
- package/src/mathRichInputHelper.js +785 -0
- package/src/mimeTypeHelper.js +201 -0
package/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# MathRichInput
|
|
2
|
+
|
|
3
|
+
This project is a math rich input component that allows users to edit a "text area" with the following key features:
|
|
4
|
+
|
|
5
|
+
1. Ability to render, insert and edit equations in the input field
|
|
6
|
+
2. A toolbar that appears on focus:
|
|
7
|
+
- Buttons for bold, italic, underline, subscript and superscript
|
|
8
|
+
- Button for accents
|
|
9
|
+
- Button for inserting equations
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
### Basic usage
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
export default class App extends Component {
|
|
18
|
+
|
|
19
|
+
constructor(props) {
|
|
20
|
+
super(props);
|
|
21
|
+
this.state = {
|
|
22
|
+
value:"", // Set this to an initial value if known
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
handleInputChange = (content, options) => {
|
|
27
|
+
this.setState({
|
|
28
|
+
value: content.value, // Note the field value on the returned content
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
<MathRichInput
|
|
34
|
+
value={this.state.value}
|
|
35
|
+
onChange={this.handleInputChange}
|
|
36
|
+
/>
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Normal usage
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
export default class App extends Component {
|
|
44
|
+
|
|
45
|
+
constructor(props) {
|
|
46
|
+
super(props);
|
|
47
|
+
this.state = {
|
|
48
|
+
value:"", // Set this to an initial value if known
|
|
49
|
+
mimeType:"", // Set this to the initial mime type of the text in value if known
|
|
50
|
+
options: {
|
|
51
|
+
useExpertMode:false,
|
|
52
|
+
selectedTab: null
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
handleInputChange = (content, options) => {
|
|
58
|
+
this.setState({
|
|
59
|
+
value: content.value,
|
|
60
|
+
mimeType: content.mimeType
|
|
61
|
+
options: options
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
<MathRichInput
|
|
67
|
+
value={this.state.value}
|
|
68
|
+
mimeType={this.state.mimeType}
|
|
69
|
+
options={this.state.options}
|
|
70
|
+
onChange={this.handleInputChange}
|
|
71
|
+
/>
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Rendering content created using MathRichInput with MathRichArea
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
<MathRichArea mimeType={this.state.mimeType}>
|
|
79
|
+
{this.state.value}
|
|
80
|
+
</MathRichArea>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
See the section on MathRichArea below for more information and alternative ways to render.
|
|
84
|
+
|
|
85
|
+
#### Mime type
|
|
86
|
+
|
|
87
|
+
In basic usage, the MathRichInput will attempt to work out the appropriate mime type for the inital value property if supplied. However, it is good practice to explicitly set the initial mime type when it is known. For normal usage you can simply set the mime type to application/x-zzish-html-math. You only need to read further if you have preexisting content in application/x-tex format.
|
|
88
|
+
|
|
89
|
+
The four supported mime types are:
|
|
90
|
+
|
|
91
|
+
1. text/plain
|
|
92
|
+
2. text/html
|
|
93
|
+
3. application/x-zzish-html-math
|
|
94
|
+
4. application/x-tex
|
|
95
|
+
|
|
96
|
+
The latter two mime types support math equations. Content in the application/x-tex mime type contains maths in tex equation format between a pair of $ symbols. Content in the application/x-zzish-html-math contains maths in tex equation format between a pair of `<math></math>` tags. Here are examples of the two types:
|
|
97
|
+
|
|
98
|
+
* "Find all solutions for $x$ when $x^2 + 4x - 2 = \sqrt{9}$"
|
|
99
|
+
* "Find `<b>`all`</b>` solutions for `<math>`x`</math>` when `<math>`x^2 + 4x - 2 = \sqrt{9}`</math>`"
|
|
100
|
+
|
|
101
|
+
Note that the application/x-zzish-html-math mime type allows for text with full html formatting richness including `<p></p>`,`<b></b>`,`<i></i>`,`<u></u>`,`<sup></sup>` and `<sub></sub>` tags.
|
|
102
|
+
|
|
103
|
+
The MathRichInput supports the four mime types above, but the key consideration for developers is choosing witheter to set the mime-type initially to one of application/x-tex or application/x-zzish-html-math.
|
|
104
|
+
|
|
105
|
+
If your content is only ever created using this MathRichInput component, then you can safely always set the mimeType to application/x-zzish-html-math. This is because, by default, the component will only ever output content in one of the first three mime types and the application/x-zzish-html-math mime type is a superset of the text/plain and text/html formats.
|
|
106
|
+
|
|
107
|
+
If, however, you have some legacy content in tex/latex format, you should set the mimeType to application/x-tex when the legacy content is known to be in tex/latex format. If you are unsure whether the content is tex or not, then you can not set a mime type and the MathRichInput will determine the best mime-type. 99% of the time the MathRichInput will choose the correct mime type.
|
|
108
|
+
|
|
109
|
+
Whatever the value and mime type of any initial content provided, the input field will always return the content in one of the first three mime types by default (via the onChange callback method):
|
|
110
|
+
|
|
111
|
+
1. text/plain
|
|
112
|
+
2. text/html
|
|
113
|
+
3. application/x-zzish-html-math
|
|
114
|
+
|
|
115
|
+
These mime types should ideally be stored along with the value and supplied to the MathRichInput and MathRichArea in future.
|
|
116
|
+
|
|
117
|
+
If you desire the output to be in tex\latex, then pass the parameter outputTex={true}. When you choose to output in tex, font styling (eg. bold) and multiline are disabled for users. Unless you have a good reason to output in tex, you should not use this settting.
|
|
118
|
+
|
|
119
|
+
#### Options
|
|
120
|
+
|
|
121
|
+
The options property is used to return the current state of the equation editor so that if the user closes and reopens the equation editor, the state is remembered. In particular it allows you to store whether the user:
|
|
122
|
+
|
|
123
|
+
* Is using the equation editor in expert mode
|
|
124
|
+
* Has selected a specific synbols tab
|
|
125
|
+
|
|
126
|
+
Note that normally options should be a global object with the same options used across all input fields. This is so that the user does not need to reselect expert mode and/or select the same tab each time they reopen the equation editor.
|
|
127
|
+
|
|
128
|
+
The options property can be initialed to null rather than set explicitly as above. The options can be saved against the users persistent settings if desired.
|
|
129
|
+
|
|
130
|
+
#### Other properties
|
|
131
|
+
|
|
132
|
+
##### enableFontStyling
|
|
133
|
+
|
|
134
|
+
(not yet implemented)
|
|
135
|
+
|
|
136
|
+
Set enableFontStyling={false} to:
|
|
137
|
+
|
|
138
|
+
* Disable the bold, italic, underline, subscript and superscript buttons on the toolbar
|
|
139
|
+
* Disalbe CTRL-B and other font styling hot keys
|
|
140
|
+
|
|
141
|
+
##### enableMultiline
|
|
142
|
+
|
|
143
|
+
(not yet implemented)
|
|
144
|
+
|
|
145
|
+
Set enableMultiline={false} to:
|
|
146
|
+
|
|
147
|
+
* Disable new lines being entered by pressing the return key
|
|
148
|
+
|
|
149
|
+
##### enableMath
|
|
150
|
+
|
|
151
|
+
Set enableMath={false} to:
|
|
152
|
+
|
|
153
|
+
* Disable the equation editor button on the toolbar
|
|
154
|
+
|
|
155
|
+
##### outputTex
|
|
156
|
+
|
|
157
|
+
(not yet implemented)
|
|
158
|
+
|
|
159
|
+
Set outputTex={true} to:
|
|
160
|
+
|
|
161
|
+
* Force output to be in tex (math equations are enclosed in a pair of $ symbols)
|
|
162
|
+
|
|
163
|
+
As a side effect, this also implicitly sets enableMultiline and enableFontStyling to false (see above).
|
|
164
|
+
|
|
165
|
+
##### editable
|
|
166
|
+
|
|
167
|
+
(not yet implemented)
|
|
168
|
+
|
|
169
|
+
Set editable={false} to purely render the value and not allow it to be edited by the user. Note that normally you would use the non-editable MathRichArea component to purely render values (it is a much lighter component).
|
|
170
|
+
|
|
171
|
+
## MathRichArea
|
|
172
|
+
|
|
173
|
+
MathRichArea is a lightweight component for rendering content created with MathRichInput.
|
|
174
|
+
|
|
175
|
+
Normal usage is as follows:
|
|
176
|
+
|
|
177
|
+
```js
|
|
178
|
+
<MathRichArea mimeType={this.state.mimeType}>
|
|
179
|
+
{this.state.value}
|
|
180
|
+
</MathRichArea>
|
|
181
|
+
```
|
|
182
|
+
However, if you want to update legacy code that is rendering plain text or tex/latex content and don't want to go through your code updating all the fields to use the MathRichArea component, you can cheat and use the MathRichArea.renderMathInNode method in componentDidUpdate and componentDidMount.
|
|
183
|
+
|
|
184
|
+
For example, assuming that you had a page containing some content:
|
|
185
|
+
|
|
186
|
+
```js
|
|
187
|
+
<div className="question">{this.state.questionText}</div>
|
|
188
|
+
<div className="answer">{this.state.answerText}</div>
|
|
189
|
+
```
|
|
190
|
+
where the question and answer text was simple text in the legacy codebase, but is not the content.value returned from a MathRichInput (and thus may - or may not - contain html or maths).
|
|
191
|
+
|
|
192
|
+
Simply add the following code:
|
|
193
|
+
|
|
194
|
+
```js
|
|
195
|
+
componentDidMount() {
|
|
196
|
+
renderMathInNode(document)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
componentDidUpdate() {
|
|
200
|
+
renderMathInNode(document)
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
The renderMathInNode method will then:
|
|
204
|
+
|
|
205
|
+
1. Search through all nodes including the supplied node and all its descendent nodes for text nodes
|
|
206
|
+
2. Analyse the text to determine if it is text/html, application/x-zzish-html-math or application/x-tex
|
|
207
|
+
3. If so convert the text for display
|
|
208
|
+
|
|
209
|
+
For short pages, the root document can be supplied as the starting node. For longer pages you may first want to select one or more nodes for processing to improve efficiency
|
|
210
|
+
|
|
211
|
+
```js
|
|
212
|
+
componentDidMount() {
|
|
213
|
+
renderMathInNode(document.getElementById("render-this-text"))
|
|
214
|
+
renderMathInNode(document.getElementById("render-this-text-too"))
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
componentDidUpdate() {
|
|
218
|
+
renderMathInNode(document.getElementById("render-this-text"))
|
|
219
|
+
renderMathInNode(document.getElementById("render-this-text-too"))
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## ToDo
|
|
224
|
+
|
|
225
|
+
The following items need to be done before moving to production
|
|
226
|
+
|
|
227
|
+
1. Automatically open Expert mode if unable to render in MathQuill.
|
|
228
|
+
2. Warn if switching from Expert mode to normal mode
|
|
229
|
+
3. Ensure try catch round all events and check best practice for react component error handling
|
|
230
|
+
|
|
231
|
+
The following items should be done before moving to production
|
|
232
|
+
|
|
233
|
+
1. Bug: Deleting first equation when characters to the left, offset incorrect
|
|
234
|
+
2. Bug: Deleting selected text when equation immediatly to left deletes the equation incorrectly
|
|
235
|
+
3. Refactor button areas in the modal to be their own fixed components
|
|
236
|
+
4. Generally refactor MathRichInput.js to move code out of file
|
|
237
|
+
|
|
238
|
+
Other things that should be done
|
|
239
|
+
|
|
240
|
+
* Expert mode: [Text] mathrm
|
|
241
|
+
* Mobile: Have tab list behave appropriately on smaller width screens (eg. convert )
|
|
242
|
+
* Mobile: Fix css grow effect for symbol buttons on mobile
|
|
243
|
+
* Tidy up equationEditorButtonsHelper.js
|
|
244
|
+
* Have tab underline match scollview position in modal
|
|
245
|
+
* Expert mode: fraction command (and all commands with ##) need to look back to find whole element to include
|
|
246
|
+
* Expert mode: Enable inserting of symbols into pure text (currently blocks as it thinks it is a tag)
|
|
247
|
+
* Expert mode: Smart fix of typying x_12 into x_{12} or x_min into x_{min}
|
|
248
|
+
* Expert mode: Inserting into prettified text does not work when first switching to expert mode
|
|
249
|
+
|
|
250
|
+
New features
|
|
251
|
+
|
|
252
|
+
* History: show matching previously entered equations as you type an equation.
|
|
253
|
+
* Common combos: for example, add extra buttons for 2 pi r and pi r^2 on hover over pi button
|