@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
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
const INLINE_LATEX_REG_EXP = /\$\$[\s\S]+?\$\$|\\\[[\s\S]+?\\\]|\\\([\s\S]+?\\\)|\$[^$\\]*(?:\\.[^$\\]*)*\$/g;
|
|
2
|
+
const BLOCL_LATEX_REG_EXP = /\$\$[\s\S]+?\$\$|\\\[[\s\S]+?\\\]/g;
|
|
3
|
+
|
|
4
|
+
export const MIME_TYPE_PLAIN_TEXT = "text/plain"
|
|
5
|
+
export const MIME_TYPE_HTML = "text/html"
|
|
6
|
+
export const MIME_TYPE_TEX = "application/x-tex"
|
|
7
|
+
export const MIME_TYPE_ZZISH_HTML_MATH = "application/x-zzish-html-math"
|
|
8
|
+
|
|
9
|
+
const LATEX_COMMAND_REG_EXP = /\\[a-zA-Z]/g
|
|
10
|
+
|
|
11
|
+
const HTML_CODES_REG_EXP = /&(#36|quot|apos|lt|gt|amp);/
|
|
12
|
+
const HTML_TAGS_REG_EXP = /<(br|basefont|hr|input|source|frame|param|area|meta|!--|col|link|option|base|img|wbr|!DOCTYPE).*?>|<(a|abbr|acronym|address|applet|article|aside|audio|b|bdi|bdo|big|blockquote|body|button|canvas|caption|center|cite|code|colgroup|command|datalist|dd|del|details|dfn|dialog|dir|div|dl|dt|em|embed|fieldset|figcaption|figure|font|footer|form|frameset|head|header|hgroup|h1|h2|h3|h4|h5|h6|html|i|iframe|ins|kbd|keygen|label|legend|li|map|mark|menu|meter|nav|noframes|noscript|object|ol|optgroup|output|p|pre|progress|q|rp|rt|ruby|s|samp|script|section|select|small|span|strike|strong|style|sub|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|track|tt|u|ul|var|video).*?<\/\2>/i
|
|
13
|
+
const HTML_MATH_TAGS_REC_EXP = /<math>/i
|
|
14
|
+
|
|
15
|
+
const WORDS_REG_EXP = /^[a-zA-Z]*[,."';:?!]*$/i
|
|
16
|
+
|
|
17
|
+
function stripDollars (stringToStrip) {
|
|
18
|
+
return stringToStrip[0] === "$" && stringToStrip[1] !== "$"
|
|
19
|
+
? stringToStrip.slice(1, -1)
|
|
20
|
+
: stringToStrip.slice(2, -2)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function isTextLatexMath(text) {
|
|
24
|
+
// We need at least two dollar signs to be latex
|
|
25
|
+
let i = text.indexOf("$")
|
|
26
|
+
if (i < 0)
|
|
27
|
+
return false
|
|
28
|
+
i = text.indexOf("$",i+1)
|
|
29
|
+
if (i < 0)
|
|
30
|
+
return false
|
|
31
|
+
|
|
32
|
+
// Lets try and extract the potentially latex nodes
|
|
33
|
+
let latexMatch = text.match(BLOCL_LATEX_REG_EXP)
|
|
34
|
+
if (latexMatch === null || latexMatch === undefined)
|
|
35
|
+
latexMatch = text.match(INLINE_LATEX_REG_EXP);
|
|
36
|
+
|
|
37
|
+
if (latexMatch === null || latexMatch === undefined || latexMatch.length === 0)
|
|
38
|
+
return false
|
|
39
|
+
|
|
40
|
+
for (let i = 0; i < latexMatch.length; i++)
|
|
41
|
+
latexMatch[i] = stripDollars(latexMatch[i])
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
// If all dollar signs are followed by a number, it probably is not latex
|
|
45
|
+
i = text.indexOf("$")
|
|
46
|
+
let probablyLatex = false
|
|
47
|
+
while (i >=0) {
|
|
48
|
+
if (i === text.length-1) {
|
|
49
|
+
probablyLatex = true
|
|
50
|
+
break
|
|
51
|
+
}
|
|
52
|
+
let c = text.charAt(i+1)
|
|
53
|
+
if (c < "0" || c > "9") {
|
|
54
|
+
probablyLatex = true
|
|
55
|
+
break
|
|
56
|
+
}
|
|
57
|
+
i = text.indexOf("$",i+1)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Note that there are other uses of a dollar sign, that couold potentially be
|
|
61
|
+
// entered. For example, if someone created a question about the use of the
|
|
62
|
+
// $ sign in excel cells or the use of the $ sign in regular expressions.
|
|
63
|
+
|
|
64
|
+
if (probablyLatex) {
|
|
65
|
+
// At this point it probably is latex, but we can check inside the latex
|
|
66
|
+
// elements for things that make it not valid latex
|
|
67
|
+
|
|
68
|
+
// Note that invalid latex does not necessarily mean it is not INTENDED
|
|
69
|
+
// to be latex. Normal text is valid latex, and invalid latex usually reflects
|
|
70
|
+
// an error in intended latex. Thus it is hard to come up for a test that indicates
|
|
71
|
+
// that text inside a pair of $ symbols is not latex
|
|
72
|
+
|
|
73
|
+
// for (let i = 0; i < latexMatch.length; i++) {
|
|
74
|
+
// if (!isValidLatex(latexMatch[i]))
|
|
75
|
+
// return false
|
|
76
|
+
// }
|
|
77
|
+
|
|
78
|
+
// If all the latex elements are empty, then we will treat it as plain text
|
|
79
|
+
let allEmpty = true
|
|
80
|
+
for (let i = 0; i < latexMatch.length; i++) {
|
|
81
|
+
if (latexMatch[i] !== "")
|
|
82
|
+
allEmpty = false
|
|
83
|
+
}
|
|
84
|
+
if (allEmpty)
|
|
85
|
+
return false
|
|
86
|
+
|
|
87
|
+
// If an element between two dollars is two or more words and only words
|
|
88
|
+
// and at least one word has three characters then we will treat it as text
|
|
89
|
+
for (let i = 0; i < latexMatch.length; i++) {
|
|
90
|
+
let words = latexMatch[i].split(" ")
|
|
91
|
+
if (words.length >= 2) {
|
|
92
|
+
let allWords = true
|
|
93
|
+
let longWord = false
|
|
94
|
+
for (let j = 0; j < words.length; j++) {
|
|
95
|
+
// console.log(j+":"+words[j])
|
|
96
|
+
if (words[j].length > 0 &&
|
|
97
|
+
WORDS_REG_EXP.test(words[j]) === false) {
|
|
98
|
+
// console.log("Not: "+words[j])
|
|
99
|
+
allWords = false
|
|
100
|
+
break
|
|
101
|
+
}
|
|
102
|
+
if (words[j].length >= 3)
|
|
103
|
+
longWord = true
|
|
104
|
+
}
|
|
105
|
+
if (allWords && longWord)
|
|
106
|
+
return false
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return true
|
|
111
|
+
} else {
|
|
112
|
+
// At this point it probably is not latex, but we can check inside the latex
|
|
113
|
+
// elements for things that make it likely to be latex, such as latex commands
|
|
114
|
+
|
|
115
|
+
for (let i = 0; i < latexMatch.length; i++) {
|
|
116
|
+
if (latexMatch[i].match(LATEX_COMMAND_REG_EXP) !== null)
|
|
117
|
+
return true
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return false
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function isTextHtml(text) {
|
|
125
|
+
if (HTML_CODES_REG_EXP.test(text))
|
|
126
|
+
return true
|
|
127
|
+
let i = text.indexOf("<")
|
|
128
|
+
if (i < 0)
|
|
129
|
+
return false
|
|
130
|
+
|
|
131
|
+
let containsHtmlTags = HTML_TAGS_REG_EXP.test(text)
|
|
132
|
+
return containsHtmlTags
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function isTextHtmlMath(text) {
|
|
136
|
+
let containsMathTags = HTML_MATH_TAGS_REC_EXP.test(text)
|
|
137
|
+
return containsMathTags
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function determineMimeType(text) {
|
|
141
|
+
if (isTextHtmlMath(text))
|
|
142
|
+
return MIME_TYPE_ZZISH_HTML_MATH
|
|
143
|
+
|
|
144
|
+
if (isTextHtml(text))
|
|
145
|
+
return MIME_TYPE_HTML
|
|
146
|
+
|
|
147
|
+
if (isTextLatexMath(text))
|
|
148
|
+
return MIME_TYPE_TEX
|
|
149
|
+
|
|
150
|
+
return MIME_TYPE_PLAIN_TEXT
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
// test = (text, mimeType) => {
|
|
155
|
+
// let result = determineMimeType(text)
|
|
156
|
+
// if (result === mimeType)
|
|
157
|
+
// return <p style={{color:"green"}}>{text}: {result}</p>
|
|
158
|
+
// else
|
|
159
|
+
// return <p style={{color:"red"}}>{text}: {result}</p>
|
|
160
|
+
// }
|
|
161
|
+
|
|
162
|
+
/*
|
|
163
|
+
{this.test("a", "text/plain")}
|
|
164
|
+
{this.test("hello world", "text/plain")}
|
|
165
|
+
{this.test("hello <b>world</b>", "text/html")}
|
|
166
|
+
{this.test("hello <math>e=mc^2</math>", "application/x-zzish-html-math")}
|
|
167
|
+
{this.test("hello <MATH>e=mc^2</MATH>", "application/x-zzish-html-math")}
|
|
168
|
+
{this.test("$a$", "application/x-tex")}
|
|
169
|
+
{this.test("$$a$$", "application/x-tex")}
|
|
170
|
+
{this.test("$$a$$ or $$b$$", "application/x-tex")}
|
|
171
|
+
{this.test("$1$", "application/x-tex")}
|
|
172
|
+
{this.test("$1.00$", "application/x-tex")}
|
|
173
|
+
{this.test("$+1.00$", "application/x-tex")}
|
|
174
|
+
{this.test("$-1.00$", "application/x-tex")}
|
|
175
|
+
{this.test("$1.00 $", "application/x-tex")}
|
|
176
|
+
{this.test("$ 1.00$", "application/x-tex")}
|
|
177
|
+
{this.test("$ 1.00 $", "application/x-tex")}
|
|
178
|
+
{this.test("If a is exactly $1.00$ then", "application/x-tex")}
|
|
179
|
+
{this.test("$1.00 $2.00", "text/plain")}
|
|
180
|
+
{this.test("Yes, $1.00 < $2.00", "text/plain")}
|
|
181
|
+
{this.test("If $x$ is big", "application/x-tex")}
|
|
182
|
+
{this.test("If I have $1.00", "text/plain")}
|
|
183
|
+
{this.test("If sugar costs $1.00 and tea costs $2.00", "text/plain")}
|
|
184
|
+
{this.test("If sugar costs $1.00 and tea \\times costs $2.00", "application/x-tex")}
|
|
185
|
+
{this.test("If sugar costs $1.00 and tea \\ times costs $2.00", "text/plain")}
|
|
186
|
+
{this.test("I love $$. What about you?", "text/plain")}
|
|
187
|
+
{this.test("I love $$$. What about you?", "text/plain")}
|
|
188
|
+
{this.test("Here is a $ and here is another $", "text/plain")}
|
|
189
|
+
{this.test("Here is a $ and here is, well , another $", "text/plain")}
|
|
190
|
+
{this.test("$a bc d$", "application/x-tex")}
|
|
191
|
+
{this.test("$abcd$", "application/x-tex")}
|
|
192
|
+
{this.test("$ab cd$", "application/x-tex")}
|
|
193
|
+
{this.test("$a bcd e$", "text/plain")}
|
|
194
|
+
{this.test("$a bcd, e$", "text/plain")}
|
|
195
|
+
{this.test("$a + bcd - e$", "application/x-tex")}
|
|
196
|
+
{this.test("$a bcd, e$", "text/plain")}
|
|
197
|
+
{this.test("$a bcd! e$", "text/plain")}
|
|
198
|
+
{this.test("$a bcd; e$", "text/plain")}
|
|
199
|
+
{this.test("$a bcd. e$", "text/plain")}
|
|
200
|
+
{this.test("$a bcd> e$", "application/x-tex")}
|
|
201
|
+
*/
|