@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.
@@ -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
+ */