@zzish/math-rich-input 0.1.1 → 0.1.3

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 CHANGED
@@ -1,13 +1,12 @@
1
1
  # MathRichInput
2
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
3
+ This project is a `MathRichInput` component that allows users to edit a "text area" with the following key features:
10
4
 
5
+ 1. Ability to render, insert and edit mathematical equations in the input field
6
+ 2. A toolbar that appears on focus with:
7
+ - Five buttons for bold, italic, underline, subscript and superscript
8
+ - A button for accents and other special characters
9
+ - A button to bring up a WYSIWIG equation editor and insert equations
11
10
 
12
11
  ## Usage
13
12
 
@@ -71,6 +70,21 @@ export default class App extends Component {
71
70
  />
72
71
  }
73
72
  ```
73
+ ### Legacy usage
74
+
75
+ By default the `MathRichInput` will output content in html via the `onChange` callback method. You can force it to output tex and plain text instead using the `outputTex` and `outputPlainText` properties as follows:
76
+
77
+ ```js
78
+ <MathRichInput
79
+ outputTex={true}
80
+ outputPlainText={true}
81
+ value={this.state.value}
82
+ mimeType={this.state.mimeType}
83
+ options={this.state.options}
84
+ onChange={this.handleInputChange}
85
+ />
86
+ ```
87
+
74
88
 
75
89
  ### Rendering content created using MathRichInput with MathRichArea
76
90
 
@@ -82,91 +96,106 @@ export default class App extends Component {
82
96
 
83
97
  See the section on MathRichArea below for more information and alternative ways to render.
84
98
 
85
- #### Mime type
99
+ ## Mime types
86
100
 
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.
101
+ In basic usage, the `MathRichInput` will attempt to work out the appropriate mime type for the inital value property if not supplied. However, it is good practice to explicitly set the initial mime type when it is known. For normal usage of `MathRichInput` using default settings, 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 `text/plain` or `application/x-tex` mime types.
88
102
 
89
103
  The four supported mime types are:
90
104
 
91
- 1. text/plain
92
- 2. text/html
93
- 3. application/x-zzish-html-math
94
- 4. application/x-tex
105
+ 1. `text/plain`
106
+ 2. `application/x-tex`
107
+ 3. `text/html`
108
+ 4. `application/x-zzish-html-math`
109
+
110
+ 2 and 4 support math equations.
111
+
112
+ Content in the `application/x-tex` mime type contains maths in tex equation format between a pair of $ symbols, or pairs of escaped round or square brackets, `\( \)` or `\[ \]`.
113
+
114
+ Content in the `application/x-zzish-html-math` contains maths in tex equation format between a pair of `<math></math>` tags.
95
115
 
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:
116
+ Here are examples of content in the two types:
97
117
 
98
118
  * "Find all solutions for $x$ when $x^2 + 4x - 2 = \sqrt{9}$"
99
119
  * "Find `<b>`all`</b>` solutions for `<math>`x`</math>` when `<math>`x^2 + 4x - 2 = \sqrt{9}`</math>`"
100
120
 
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.
121
+ 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
122
 
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.
123
+ 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 `plain/text`, `application/x-tex` or `application/x-zzish-html-math`.
104
124
 
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.
125
+ If your content is only ever created using this `MathRichInput` component with default settings, 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 as `text/html` or `application/x-zzish-html-math` and the `application/x-zzish-html-math` mime type is a superset of the `text/html` mime type.
106
126
 
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.
127
+ If, however, you have some legacy content in plain text or tex/latex format, you should ideally set the mimeType as appropriate. If you are unsure as to the type of your content, then you can leave the mime type unset and the `MathRichInput` will choose the best mime-type automatically. It will generally make good choices, but it will make the wrong choice on plain text such as the following:
108
128
 
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):
129
+ * "To bold text in html you should put the text betweeen `<b>` and `<\b>` tags"
110
130
 
111
- 1. text/plain
112
- 2. text/html
113
- 3. application/x-zzish-html-math
131
+ In this example, the automatic detection will assume this is html, as it will identify the bold html tags. It will thus bold the word 'and'. It is not possible for the automatic detection to determine that this was in fact plain text.
114
132
 
115
- These mime types should ideally be stored along with the value and supplied to the MathRichInput and MathRichArea in future.
133
+ Whatever the value and mime type of any initial content provided, the input field will always return the content in one of the two html mime types by default (via the onChange callback method):
116
134
 
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.
135
+ 1. `text/html`
136
+ 3. `application/x-zzish-html-math`
118
137
 
119
- #### Options
138
+ These mime types should ideally be stored along with the value and supplied back to the `MathRichInput` and `MathRichArea` in future.
139
+
140
+ If you desire the output to be `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.
141
+
142
+ By default, any output content that does not contain multiple lines (i.e. `<p></p>` tags), any html font styling (e.g. `<b></b>`), or any math elements will still be returned as `text\html` and any special html characters will be converted to their html codings (for example `<` will be converted to `&gt;`). If required you can choose to have content that does not need any html or math formatting returned as plain text using `outputPlainText={true}`.
143
+
144
+ In general, unless you have a *very* good reason to, you should not set `outputTex={true}` or `outputPlainText={true}` and you should have your content returned as html (`text/html`) or html math (`application/x-zzish-html-math`) as happens with the default settings.
145
+
146
+ ## Options
120
147
 
121
148
  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
149
 
123
150
  * Is using the equation editor in expert mode
124
- * Has selected a specific synbols tab
151
+ * Has selected a specific symbols tab
125
152
 
126
153
  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
154
 
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.
155
+ The options property can be initialised to null rather than set explicitly as above. The options can be saved against the user's persistent user settings if desired.
129
156
 
130
157
  #### Other properties
131
158
 
132
159
  ##### enableFontStyling
133
160
 
134
- (not yet implemented)
135
-
136
- Set enableFontStyling={false} to:
161
+ Set `enableFontStyling={false}` to:
137
162
 
138
163
  * Disable the bold, italic, underline, subscript and superscript buttons on the toolbar
139
164
  * Disalbe CTRL-B and other font styling hot keys
140
165
 
141
166
  ##### enableMultiline
142
167
 
143
- (not yet implemented)
144
-
145
- Set enableMultiline={false} to:
168
+ Set `enableMultiline={false}` to:
146
169
 
147
170
  * Disable new lines being entered by pressing the return key
148
171
 
149
172
  ##### enableMath
150
173
 
151
- Set enableMath={false} to:
174
+ Set `enableMath={false}` to:
152
175
 
153
176
  * Disable the equation editor button on the toolbar
154
177
 
155
178
  ##### outputTex
156
179
 
157
- (not yet implemented)
158
-
159
- Set outputTex={true} to:
180
+ Set `outputTex={true}` to:
160
181
 
161
182
  * Force output to be in tex (math equations are enclosed in a pair of $ symbols)
162
183
 
163
- As a side effect, this also implicitly sets enableMultiline and enableFontStyling to false (see above).
184
+ As a side effect, this also implicitly sets `enableMultiline` and `enableFontStyling` to false (see above).
185
+
186
+ ##### outputPlainText
187
+
188
+ Set `outputPlainText={true}` to:
189
+
190
+ * Force output to be in plain text when the input text contains no html and no maths
191
+
192
+ Note that this does not disable multiline or font styling
164
193
 
165
194
  ##### editable
166
195
 
167
196
  (not yet implemented)
168
197
 
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).
198
+ 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
199
 
171
200
  ## MathRichArea
172
201
 
@@ -187,7 +216,7 @@ For example, assuming that you had a page containing some content:
187
216
  <div className="question">{this.state.questionText}</div>
188
217
  <div className="answer">{this.state.answerText}</div>
189
218
  ```
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).
219
+ where the question and answer text was simple text in any one of the four supported mime types.
191
220
 
192
221
  Simply add the following code:
193
222
 
package/dist/index.js CHANGED
@@ -23031,6 +23031,4 @@ var MathRichArea = /*#__PURE__*/function (_React$Component) {
23031
23031
  return MathRichArea;
23032
23032
  }(React.Component);
23033
23033
 
23034
- console.log("hello charles");
23035
-
23036
23034
  export { MathRichArea, MathRichInput, renderMathInNode };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zzish/math-rich-input",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "React component for user to enter rich text with embedded math equations.",
5
5
  "repository": {
6
6
  "type": "git",
package/rollup.config.js CHANGED
@@ -9,7 +9,7 @@ export default {
9
9
  input: "src/index.js",
10
10
  output: {
11
11
  file: "dist/index.js",
12
- // format: "cjs",
12
+ format: "cjs",
13
13
  },
14
14
  plugins: [
15
15
  nodeResolve({ main: true }),
@@ -3,7 +3,7 @@ import React from 'react'
3
3
  import katex from "katex";
4
4
  import {setupKatex} from "./katexHelper"
5
5
  import {rawTextToHtml} from './mathRichInputHelper'
6
- import {MIME_TYPE_TEX, MIME_TYPE_HTML, MIME_TYPE_ZZISH_HTML_MATH,
6
+ import {MIME_TYPE_TEX, MIME_TYPE_HTML, MIME_TYPE_ZZISH_HTML_MATH,
7
7
  isTextLatexMath, isTextHtml, isTextHtmlMath} from './mimeTypeHelper'
8
8
 
9
9
 
@@ -96,8 +96,13 @@ export default class MathRichArea extends React.Component {
96
96
  }
97
97
 
98
98
  render() {
99
- let html = rawTextToHtml(katex, this.props.children, this.props.mime_type)
99
+ // console.log("Mime type: "+this.props.mimeType)
100
+ let html = rawTextToHtml(katex, this.props.children, this.props.mimeType)
101
+ // console.log("html: "+html)
100
102
 
101
103
  return <span dangerouslySetInnerHTML={{__html: html}}></span>
102
104
  }
103
- }
105
+ }
106
+
107
+
108
+
@@ -9,6 +9,7 @@ import Toolbar from './Toolbar'
9
9
  import {
10
10
  isKatexNode,
11
11
  elementToMarkedRawText,
12
+ removeEncodingIfPlainText,
12
13
  rawTextToHtml,
13
14
  getLatex,
14
15
  setRangeParams,
@@ -147,18 +148,23 @@ export default class MathRichInput extends React.Component {
147
148
  // /<\s*sub[^>]*>(.*?)<\s*\/\s*sub\s*>/i.test(text)
148
149
  // }
149
150
 
150
- getMimeType(isHtml, hasMath) {
151
- if (isHtml) {
152
- if (hasMath)
153
- return MIME_TYPE_ZZISH_HTML_MATH
154
- else
155
- return MIME_TYPE_HTML
156
- } else {
157
- if (hasMath)
151
+ getMimeType(hasHtml, hasMath) {
152
+ let outputTex = this.props.outputTex ?? false
153
+ let outputPlainText = this.props.outputPlainText ?? false
154
+
155
+ if (outputTex) {
156
+ if (hasMath || !outputPlainText)
158
157
  return MIME_TYPE_TEX
159
158
  else
160
159
  return MIME_TYPE_PLAIN_TEXT
161
- }
160
+ }
161
+
162
+ if (hasMath)
163
+ return MIME_TYPE_ZZISH_HTML_MATH
164
+ if (hasHtml || !outputPlainText)
165
+ return MIME_TYPE_HTML
166
+
167
+ return MIME_TYPE_PLAIN_TEXT
162
168
  }
163
169
 
164
170
  _countNodeTypes = () => {
@@ -420,6 +426,7 @@ export default class MathRichInput extends React.Component {
420
426
 
421
427
  let nodeCounts = this._countNodeTypes()
422
428
  let mimeType = this.getMimeType(nodeCounts.html > 0, nodeCounts.math > 0)
429
+ raw_text = removeEncodingIfPlainText(raw_text, mimeType, this.enableHtml())
423
430
 
424
431
  this.applyChangesToComponent(raw_text, mimeType, new_rangeParams,
425
432
  this.props.useExpertMode, this.props.selectedTab)
@@ -697,6 +704,7 @@ export default class MathRichInput extends React.Component {
697
704
 
698
705
  let nodeCounts = this._countNodeTypes()
699
706
  let mimeType = this.getMimeType(nodeCounts.html > 0, true)
707
+ raw_text = removeEncodingIfPlainText(raw_text, mimeType, this.enableHtml())
700
708
 
701
709
  this.applyChangesToComponent(raw_text,
702
710
  mimeType,
@@ -991,7 +999,7 @@ export default class MathRichInput extends React.Component {
991
999
  handleInput = (event) => {
992
1000
  try {
993
1001
  // console.log("handleInput")
994
- const raw_text = elementToMarkedRawText(this.editableDiv, null, 0, this.enableHtml())
1002
+ let raw_text = elementToMarkedRawText(this.editableDiv, null, 0, this.enableHtml())
995
1003
  const params = this._getRangeParams()
996
1004
  if (params === null || params === undefined)
997
1005
  console.error("Could not get range params from input field")
@@ -1004,6 +1012,8 @@ export default class MathRichInput extends React.Component {
1004
1012
 
1005
1013
  let nodeCounts = this._countNodeTypes()
1006
1014
  let mimeType = this.getMimeType(nodeCounts.html > 0, nodeCounts.math > 0)
1015
+ raw_text = removeEncodingIfPlainText(raw_text, mimeType, this.enableHtml())
1016
+
1007
1017
  this.applyChangesToComponent(raw_text, mimeType, params,
1008
1018
  this.props.useExpertMode, this.props.selectedTab)
1009
1019
  } catch (error) {
@@ -1305,6 +1315,7 @@ export default class MathRichInput extends React.Component {
1305
1315
  mimeType = this.getMimeType(nodeCounts.html > 0, nodeCounts.katex > 1)
1306
1316
  else
1307
1317
  mimeType = this.getMimeType(nodeCounts.html > 0, nodeCounts.katex > 0)
1318
+ new_raw_text = removeEncodingIfPlainText(new_raw_text, mimeType, this.enableHtml())
1308
1319
 
1309
1320
  this.applyChangesToComponent(new_raw_text, mimeType, new_rangeParams,
1310
1321
  this.props.useExpertMode, this.props.selectedTab)
@@ -1346,6 +1357,7 @@ export default class MathRichInput extends React.Component {
1346
1357
 
1347
1358
  let nodeCounts = this._countNodeTypes()
1348
1359
  let mimeType = this.getMimeType(nodeCounts.html > 0, true)
1360
+ new_raw_text = removeEncodingIfPlainText(new_raw_text, mimeType, this.enableHtml())
1349
1361
 
1350
1362
  this.applyChangesToComponent(new_raw_text, mimeType, new_rangeParams,
1351
1363
  this.props.useExpertMode, this.props.selectedTab)
@@ -1430,6 +1442,8 @@ export default class MathRichInput extends React.Component {
1430
1442
  new_rangeParams.startOffset = new_rangeParams.startOffset + new_text.length
1431
1443
  new_rangeParams.endOffset = new_rangeParams.endOffset + new_text.length
1432
1444
 
1445
+ new_raw_text = removeEncodingIfPlainText(new_raw_text, this.state.mimeType, this.enableHtml())
1446
+
1433
1447
  this.applyChangesToComponent(new_raw_text, this.state.mimeType, new_rangeParams,
1434
1448
  this.props.useExpertMode, this.props.selectedTab)
1435
1449
  } catch (error) {
@@ -1460,6 +1474,8 @@ export default class MathRichInput extends React.Component {
1460
1474
  console.log("Old nodes")
1461
1475
  console.log(this.editableDiv.childNodes)
1462
1476
 
1477
+ new_raw_text = removeEncodingIfPlainText(new_raw_text, this.state.mimeType, this.enableHtml())
1478
+
1463
1479
  this.applyChangesToComponent(new_raw_text, this.state.mimeType, new_rangeParams,
1464
1480
  this.props.useExpertMode, this.props.selectedTab)
1465
1481
  } catch (error) {
@@ -1498,6 +1514,8 @@ export default class MathRichInput extends React.Component {
1498
1514
  console.log("Old nodes")
1499
1515
  console.log(this.editableDiv.childNodes)
1500
1516
 
1517
+ new_raw_text = removeEncodingIfPlainText(new_raw_text, this.state.mimeType, this.enableHtml())
1518
+
1501
1519
  this.applyChangesToComponent(new_raw_text, this.state.mimeType, new_rangeParams,
1502
1520
  this.props.useExpertMode, this.props.selectedTab)
1503
1521
  } catch (error) {
@@ -1521,6 +1539,7 @@ export default class MathRichInput extends React.Component {
1521
1539
  new_rangeParams.startOffset = new_rangeParams.startOffset + new_char.length + 1
1522
1540
  new_rangeParams.endOffset = new_rangeParams.endOffset + new_char.length + 1
1523
1541
 
1542
+ new_raw_text = removeEncodingIfPlainText(new_raw_text, this.state.mimeType, this.enableHtml())
1524
1543
  this.applyChangesToComponent(new_raw_text, this.state.mimeType, new_rangeParams,
1525
1544
  this.props.useExpertMode, this.props.selectedTab)
1526
1545
  } catch (error) {
@@ -1547,6 +1566,7 @@ export default class MathRichInput extends React.Component {
1547
1566
  else
1548
1567
  new_raw_text = removeMarks(replaceCharacterBeforeMarks(raw_text, new_char))
1549
1568
 
1569
+ new_raw_text = removeEncodingIfPlainText(new_raw_text, this.state.mimeType, this.enableHtml())
1550
1570
  this.applyChangesToComponent(new_raw_text, this.state.mimeType, new_rangeParams,
1551
1571
  this.props.useExpertMode, this.props.selectedTab)
1552
1572
  } catch (error) {
package/src/index.js CHANGED
@@ -1,5 +1,9 @@
1
- export { default as MathRichInput } from "./MathRichInput";
2
- export { default as MathRichArea } from "./MathRichArea";
3
- export { renderMathInNode } from "./MathRichArea";
4
-
1
+ import MathRichInput from "./MathRichInput";
2
+ import MathRichArea from "./MathRichArea";
3
+ import { renderMathInNode } from "./MathRichArea";
5
4
 
5
+ export {
6
+ MathRichInput,
7
+ MathRichArea,
8
+ renderMathInNode
9
+ }
@@ -1,22 +1,34 @@
1
1
  import { determineMimeType } from './mimeTypeHelper'
2
2
 
3
- export const RAW_TEXT_MATH_START_TAG_TEX = "$"
4
- export const RAW_TEXT_MATH_END_TAG_TEX = "$"
3
+ export const RAW_TEXT_MATH_START_TAG_TEX = "\\["
4
+ export const RAW_TEXT_MATH_END_TAG_TEX = "\\]"
5
5
  export const RAW_TEXT_MATH_START_TAG_HTML_MATH = "<math>"
6
6
  export const RAW_TEXT_MATH_END_TAG_HTML_MATH = "</math>"
7
7
 
8
8
  const INLINE_TEX_REG_EXP = /\$\$[\s\S]+?\$\$|\\\[[\s\S]+?\\\]|\\\([\s\S]+?\\\)|\$[^$\\]*(?:\\.[^$\\]*)*\$/g;
9
9
  const BLOCK_TEX_REG_EXP = /\$\$[\s\S]+?\$\$|\\\[[\s\S]+?\\\]/g;
10
10
 
11
+ // const INLINE_TEX_REG_EXP = /(?<!\\)\$[\s\S]+?(?<!\\)\$/g
12
+
13
+ // In general, (?<!Y)X matches an X that is not preceded by a Y. so (?<!\\)\$
14
+
15
+ // const INLINE_TEX_REG_EXP = /(?<!\\)(?:((?<!\$)\${1,2}(?!\$))|(\\\()|(\\\[)|(\\begin\{equation\}))(?(1)(.*?)(?<!\\)(?<!\$)\1(?!\$)|(?:(.*(?R)?.*)(?<!\\)(?:(?(2)\\\)|(?(3)\\\]|\\end\{equation\})))))/
16
+
17
+
11
18
  // const HTML_MATH_REG_EXP = /<math>.*?<\/math>/gi;
12
19
  const HTML_MATH_REG_EXP = /<math>[\s\S]*?<\/math>/gi;
13
20
 
14
21
  const SPAN_OPEN_BASE = "<span class=\"base\">"
15
22
  const SPAN_CLOSE = "</span>"
16
23
 
17
- const MARK = "_M_A_R_K_"
24
+ const MARK = String.fromCharCode(0)
25
+ // const MARK = "_M_A_R_K_"
18
26
  const MARK_REG_EXP = new RegExp(MARK, "g")
19
27
 
28
+ const TEMP_CHAR = String.fromCharCode(1)
29
+ const TEMP_CHAR_REG_EXP = new RegExp(TEMP_CHAR, "g")
30
+ const DOLLAR_SLASH_REG_EXP = /\\\$/g
31
+
20
32
  const SMALL_SPACE_CHAR_CODE = 8203
21
33
  const SMALL_SPACE = String.fromCharCode(SMALL_SPACE_CHAR_CODE)
22
34
  const SMALL_SPACE_REG_EXP = new RegExp(SMALL_SPACE, "g")
@@ -195,7 +207,6 @@ export function getLatex(node) {
195
207
  // <annotation encoding="application/x-tex">L' = {L}{\sqrt{1-\frac{v^2}{c^2}}}</annotation>
196
208
  let annotation = getFirstDescendentByTagName(node, "annotation")
197
209
  let latex = annotation.childNodes[0].nodeValue
198
- latex = decodeLatex(latex)
199
210
  return latex
200
211
  } catch (error) {
201
212
  console.error(error)
@@ -211,7 +222,7 @@ function encodeToHtml(text) {
211
222
  text = text.replace(/</g,"&lt;")
212
223
  text = text.replace(/'/g,"&apos;")
213
224
  text = text.replace(/"/g,"&quot;")
214
- text = text.replace(/\$/g,"&#36;")
225
+ text = text.replace(/\$/g,"&#36;")
215
226
  return text
216
227
  }
217
228
 
@@ -247,38 +258,57 @@ var decodeFromHtml = (function() {
247
258
  // }
248
259
 
249
260
  // Note we don't need to encode it so do nothing here
250
- function encodeLatex(text) {
261
+ function encodeToLatex(text) {
251
262
  // console.log("Pre-encoded: "+text)
263
+ text = text.replace(/\$/g,"\\$")
252
264
  // console.log("Post-encoded: "+text)
253
265
  return text
254
266
  }
255
267
 
256
268
  // Note we don't need to decode it so do nothing here
257
- function decodeLatex(text) {
269
+ function decodeFromLatex(text) {
258
270
  // console.log("Pre-decoded: "+text)
271
+ text = text.replace(/\\\$/g,"$")
259
272
  // console.log("Post-decoded: "+text)
260
273
  return text
261
274
  }
262
275
 
263
- function addText(arrayOfText, text, mark, offset) {
276
+ export function removeEncodingIfPlainText(text, mimeType, useHtmlMath) {
277
+ if (mimeType !== MIME_TYPE_PLAIN_TEXT)
278
+ return text
279
+
280
+ if (useHtmlMath)
281
+ return decodeFromHtml(text)
282
+ else
283
+ return decodeFromLatex(text)
284
+ }
285
+
286
+ function addText(arrayOfText, text, mark, offset, useHtmlMath=true) {
264
287
  // console.log("Mark: "+mark)
265
288
  if (offset === 0) {
266
289
  if (mark) {
267
290
  arrayOfText.push(MARK)
268
- // arrayOfText.push(" ")
269
291
  arrayOfText.push(MARK)
270
292
  }
271
293
  arrayOfText.push(text)
272
294
  } else {
273
- let decoded = decodeFromHtml(text)
274
- // console.log("Decoded: "+decoded)
275
- arrayOfText.push(encodeToHtml(decoded.substring(0,offset)))
276
- if (mark) {
277
- arrayOfText.push(MARK)
278
- // arrayOfText.push(" ")
279
- arrayOfText.push(MARK)
295
+ if (useHtmlMath) {
296
+ let decoded = decodeFromHtml(text)
297
+ arrayOfText.push(encodeToHtml(decoded.substring(0,offset)))
298
+ if (mark) {
299
+ arrayOfText.push(MARK)
300
+ arrayOfText.push(MARK)
301
+ }
302
+ arrayOfText.push(encodeToHtml(decoded.substring(offset)))
303
+ } else {
304
+ let decoded = decodeFromLatex(text)
305
+ arrayOfText.push(encodeToLatex(decoded.substring(0,offset)))
306
+ if (mark) {
307
+ arrayOfText.push(MARK)
308
+ arrayOfText.push(MARK)
309
+ }
310
+ arrayOfText.push(encodeToLatex(decoded.substring(offset)))
280
311
  }
281
- arrayOfText.push(encodeToHtml(decoded.substring(offset)))
282
312
  }
283
313
  }
284
314
 
@@ -291,7 +321,7 @@ function addTextForNode(node, arrayOfText, nodeToMark=null, offset=0, useHtmlMat
291
321
  try {
292
322
  if (isTextNode(node)) {
293
323
  addText(arrayOfText,
294
- useHtmlMath ? encodeToHtml(node.nodeValue) : node.nodeValue,
324
+ useHtmlMath ? encodeToHtml(node.nodeValue) : encodeToLatex(node.nodeValue),
295
325
  mark, offset, useHtmlMath)
296
326
  } else if (isBrNode(node)) {
297
327
  useHtmlMath && arrayOfText.push("<br>")
@@ -305,7 +335,7 @@ function addTextForNode(node, arrayOfText, nodeToMark=null, offset=0, useHtmlMat
305
335
  if (mark)
306
336
  arrayOfText.push(MARK)
307
337
  arrayOfText.push(useHtmlMath ? RAW_TEXT_MATH_START_TAG_HTML_MATH : RAW_TEXT_MATH_START_TAG_TEX)
308
- arrayOfText.push(encodeLatex(getLatex(node)))
338
+ arrayOfText.push(getLatex(node))
309
339
  arrayOfText.push(useHtmlMath ? RAW_TEXT_MATH_END_TAG_HTML_MATH : RAW_TEXT_MATH_END_TAG_TEX)
310
340
  if (mark)
311
341
  arrayOfText.push(MARK)
@@ -350,7 +380,9 @@ export function elementToMarkedRawText(element, nodeToMark=null, offset=0, useHt
350
380
 
351
381
  // remove any zero-width spaces we added to the html
352
382
  raw_text = raw_text.replace(SMALL_SPACE_REG_EXP,'')
353
-
383
+
384
+ console.log("Marked raw text: " + raw_text)
385
+
354
386
  return raw_text
355
387
  }
356
388
 
@@ -444,23 +476,38 @@ export function rawTextToHtml(katex, string, mimeType) {
444
476
  mimeType = determineMimeType(string)
445
477
 
446
478
  if (mimeType === MIME_TYPE_PLAIN_TEXT)
447
- return string
479
+ return encodeToHtml(string)
448
480
 
449
- let parseAsTex = false
450
- if (mimeType === MIME_TYPE_TEX || mimeType === MIME_TYPE_LATEX)
481
+ let parseAsTex
482
+ if (mimeType === MIME_TYPE_TEX ||
483
+ mimeType === MIME_TYPE_LATEX)
451
484
  parseAsTex = true
452
- if (!parseAsTex && (mimeType !== MIME_TYPE_HTML && mimeType !== MIME_TYPE_ZZISH_HTML_MATH)) {
485
+ else if (mimeType === MIME_TYPE_HTML ||
486
+ mimeType === MIME_TYPE_ZZISH_HTML_MATH)
487
+ parseAsTex = false
488
+ else {
489
+ parseAsTex = false
453
490
  console.error("Unknown mime type: "+mimeType)
454
491
  }
455
492
 
493
+ // console.log("Original string: "+string)
494
+ if (parseAsTex)
495
+ string = string.replace(DOLLAR_SLASH_REG_EXP, TEMP_CHAR)
496
+ // console.log("Modded string: "+string)
497
+
456
498
  const stringElements = string.split(parseAsTex ? INLINE_TEX_REG_EXP : HTML_MATH_REG_EXP);
457
499
 
458
500
  // Insert small space at start of first element if it is an empty element
459
501
  if (stringElements[0] === "") // This means the original string stars with latex
460
502
  stringElements[0] = "&#" + SMALL_SPACE.charCodeAt(0)
461
503
 
462
- // Insert small space at end of <p></p> elements so that empty lines get rendered
463
- if (mimeType === MIME_TYPE_ZZISH_HTML_MATH || mimeType === MIME_TYPE_HTML) {
504
+ if (parseAsTex) {
505
+ for (let i = 0; i <stringElements.length; i++) {
506
+ stringElements[i] = stringElements[i].replace(TEMP_CHAR_REG_EXP, "$")
507
+ stringElements[i] = encodeToHtml(stringElements[i])
508
+ }
509
+ } else {
510
+ // Insert small space at end of <p></p> elements so that empty lines get rendered
464
511
  for (let i = 0; i <stringElements.length; i++)
465
512
  stringElements[i] = stringElements[i].replace(P_TAG_REG_EXP, P_ELEMENT_SMALL_SPACE)
466
513
  }
@@ -476,8 +523,15 @@ export function rawTextToHtml(katex, string, mimeType) {
476
523
 
477
524
  if (latexElements[i]) {
478
525
  let element = latexElements[i]
479
- const type = parseAsTex ? getDisplayType(element) : "inline"
480
- element = parseAsTex ? stripDollars(element) : stripTags(element)
526
+ let type
527
+ if (parseAsTex) {
528
+ type = getDisplayType(element)
529
+ element = stripDollars(element)
530
+ element = element.replace(TEMP_CHAR_REG_EXP, "\\$")
531
+ } else {
532
+ type = "inline"
533
+ element = stripTags(element)
534
+ }
481
535
 
482
536
  let renderedElement = renderLatexString(katex, element, type)
483
537
  renderedElement = renderedElement + "&#"+SMALL_SPACE.charCodeAt(0)
@@ -25,6 +25,9 @@ export function isTextLatexMath(text) {
25
25
  let i = text.indexOf("$")
26
26
  if (i < 0)
27
27
  return false
28
+ let j = text.indexOf("\\$")
29
+ if (j >=0)
30
+ return true
28
31
  i = text.indexOf("$",i+1)
29
32
  if (i < 0)
30
33
  return false